I have a group of 2 radio buttons and I need to know when the user clicks on one of them.
One of these 2 radio buttons must be selected by default (at page creation).
Why the check callback is called when I select the radiobutton from code? How can I differentiate them ? It bothers me since when the user perform the action, I must perform a web request, but when I select it from code at init time, it mustn't do any req.
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
Search(ContractTextBox.Text, true);
}
<ItemsControl ItemsSource="{Binding SelectedMainSearchItem.SubLevels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="10">
<RadioButton Content="{Binding Name}"
GroupName="ExclusiveGroupL3"
IsChecked="{Binding IsSelected, Mode=TwoWay}"
Checked="RadioButton_Checked"
FontSize="18"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate
The usual way to deal with a situation like this is to define a bool property to use as a 'flag':
private bool isUserSelection = true;
...
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
if (isUserSelection) Search(ContractTextBox.Text, true);
}
And when you set the CheckBox value programmatically, set the flag to false:
isUserSelection = false;
SetCheckBoxValue(true);
isUserSelection = true;
Related
<helpers:CustomGrid Grid.Row="0"
Margin="0"
AutoGenerateColumns="None"
x:Name="DataGrid"
IsTabStop="False"
ItemsSource="{Binding Orders}"
CurrentItem="{Binding CurrentOrder}">
<helpers:CustomGrid.View>
<dxg:TableView Name="TView"
AllowResizing="True"
NavigationStyle="Cell"
ShowFixedTotalSummary="True"
AllowLeaveFocusOnTab="True"
HorizontalScrollbarVisibility="Auto"
VerticalScrollbarVisibility="Auto"/>
</helpers:CustomGrid.View>
I can't find any property to set to get a row automatically, even tried in my customgrid:
public CustomGrid()
{
ItemsSourceChanged += OnItemsSourceChanged;
}
private void OnItemsSourceChanged(object sender, ItemsSourceChangedEventArgs e)
{
}
Orders is a ObservableCollection.
But it won't hit because I am adding range to my ObservableCollection and not creating a new (and thats how I want it)
Any suggestions how to do this?
It all depends but... You could register to the Loaded event of the user control that contains your dataGrid and then perform a BeginInvoke() that sets the CurrentOrder on the view model and then again issue another BeginInvoke() to set focus.
Example:
public CustomGrid()
{
Loaded += CustomGrid_Loaded;
}
void CustomGrid_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
Dispatcher.BeginInvoke(new System.Action(() =>
{
var vm = DataContext as PageViewModel;
vm.CurrentOrder = vm.Orders[0];
//now set focus..
dataGrid.Focus(); //sometimes you may need to issue another BeginInvoke() when you hijack the event model
If you want to have a focused row when the GridControl is rendered, you can set DataControlBase.AllowInitiallyFocusedRow to true.
<helpers:CustomGrid Grid.Row="0"
Margin="0"
AutoGenerateColumns="None"
x:Name="DataGrid"
IsTabStop="False"
ItemsSource="{Binding Orders}"
CurrentItem="{Binding CurrentOrder}"
AllowInitiallyFocusedRow="True">
If you want to have the first row selected anytime the GridControl gets focused, you can do it with a custom TableView implementation (or Behavior).
public class CustomTableView : TableView
{
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (FocusedRowHandle < 0)
FocusedRowHandle = (DataControl as GridControl).GetRowHandleByListIndex(0);
}
}
I am new to WPF,
In my mainWindow I have multiple TextBox, so whenever a user enters different inputs in these textbox I want to implement those changes in the code behind, as soon as user leaves the focus of the textbox.
For example, my textBox looks like this:
<TextBox Name="SpiralAngleTextBox"
Grid.Column="1" Grid.Row="4"
Margin="5,5,5,5" SelectedText="0"/>
I am not looking to do any kind of input validation. What I want is to trigger some calculations or call a function whenever the TextBox leaves focus after contents of TextBox is updated.
You can write an EventHandler
<TextBox Name="SpiralAngleTextBox"
Grid.Column="1" Grid.Row="4"
Margin="5,5,5,5" SelectedText="0" LostFocus="SpiralAngleTextBox_LostFocus"/>
and in the xaml.cs
private void SpiralAngleTextBox_LostFocus(object sender, RoutedEventArgs e)
{
foo();
}
If you just want it to do stuff when the textbox content changes you can try something like this:
<TextBox Name="SpiralAngleTextBox"
Grid.Column="1" Grid.Row="4"
Margin="5,5,5,5" SelectedText="0" LostFocus="SpiralAngleTextBox_LostFocus"
TextChanged="SpiralAngleTextBox_TextChanged"/>
and in the xaml.cs
bool hasChanged;
private void SpiralAngleTextBox_LostFocus(object sender, RoutedEventArgs e)
{
if(hasChanged)
foo();
hasChanged = false;
}
private void SpiralAngleTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
hasChanged = true;
}
All you need to do is to bind to TextBox.Text
<TextBox Text="{Binding MyProperty}" />
Where MyProperty is some property in your code-behind. This is because TextBox.Text updates on lost focus (UpdateSourceTrigger=LostFocus by default.) You can learn more here: https://learn.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-control-when-the-textbox-text-updates-the-source
I ve a list from sharepoint and i collect from this list an hyperlink.
As i want my textbox to be like an hyperlink I ve added an event on mousedown to open this hyperlink, My concern is how to collect this hyperlink in the codebehind with the sender.
For the moment I've just hide this hyperlink in the tooltip maybe i can manage this differently any suggestion will be grantly appreciated.
My point so far, i don't know how to get this tooltip in the code behind.
Thanks
My XAML Code :
<ListBox Name="ListboxTips" ItemsSource="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=Picture}" Height="20"></Image>
<TextBlock MouseDown="TextBlock_MouseDown_URL" TextDecorations="Underline"
Margin="10,10,20,10" Width="160" TextWrapping="Wrap"
Text="{Binding Path=TitleTip}"
ToolTip="{Binding Path=URL}"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My code behind :
foreach (SPSClient.ListItem item in TipsList)
{
var tips = new Tips();
tips.TitleTip = item.FieldValues.Values.ElementAt(1).ToString();
tips.App = item.FieldValues.Values.ElementAt(4).ToString();
// get the Hyperlink field URL value
tips.URL = ((FieldUrlValue)(item["LinkDoc"])).Url.ToString();
//should collect the description of the url
//tips.URLdesc = ((FieldUrlValue)(item["LinkDoc"])).Description.ToString();
tips.Picture = item.FieldValues.Values.ElementAt(4).ToString();
colTips.Add(tips);
}
ListboxTips.DataContext = colTips;
....
private void TextBlock_MouseDown_URL(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//string test = (ToolTip)(sender as Control).ToString();
System.Diagnostics.Process.Start("http://www.link.com");
//System.Diagnostics.Process.Start(test);
}
Thanks a lot,
You can just access the property directly. It is not elegant, but will work!
private void TextBlock_MouseDown_URL(object sender, MouseButtonEventArgs e)
{
TextBlock txtBlock = sender as TexBlock;
// just access the property
string url = txtBlock.ToolTip as string;
}
A more elegant approach might be to use a Button, Hyperlink or something that exposes a Command, so that you can bind the 'click' action to a command on your view model that performs the action you wish to execute.
usually you stick any data you want to trespass somewhere to Tag attribute.
<TextBlock .. Tag="{Binding Path=URL}" />
This is easily retrievable as a public property:
private void TextBlock_MouseDown_URL(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var tb = sender as TextBlock;
if(tb != null)
{
var neededUrl = tb.Tag;
}
}
How do i access the object UserNames, that is bound to the list??
What i did so far:
Item of the list is object in my case:
new List<UserNames>();
this.users.Add(new UserNames() {Id = 1, UserName = "name 1"});
I am using data template for which i have label and button.
My List is as follows:
<ListBox Grid.Column="1" Grid.Row="1" Name="listBox1" ItemsSource="{Binding}" SelectedValuePath="Id">
<ListBox.ItemTemplate>
<DataTemplate>
<WrapPanel Orientation="Vertical">
<StackPanel>
<Label Content="{Binding UserName}" />
</StackPanel>
<StackPanel Name="ButtonStackPanel">
<Button Name="MyButton" Content="Click Me" Click="MyButton_Click">
</Button>
</StackPanel>
</WrapPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Where my method for Button is. As you can see i did try to utilise the parent option, but without sucess
private void MyButton_Click(object sender, RoutedEventArgs e)
{
//StackPanel panel = (StackPanel)((Button)sender).Parent;
//WrapPanel wrapPanel = (WrapPanel) panel.Parent;
//ListItem listItem = (ListItem) wrapPanel.Parent;
//ListBox box = (ListBox) listItem.Parent;
//UserNames itemToReport = (UserNames) (box.SelectedItem);
//MessageBox.Show(itemToReport.UserName);
}
You can use the Button's DataContext, since it will be your UserName object
private void MyButton_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
UserNames data = b.DataContext as UserNames;
MessageBox.Show(data.UserName);
}
I've always thought that with WPF, your application is the DataContext, while the UI objects like Buttons, ListBoxes, TextBoxes, etc are simply a pretty layer that sits on top of the DataContext to allow the User to interact with it.
In the XAML, set the Tag property to the current item.
In the click handler, cast it back.
Usernames user = (sender as Button).Tag as Usernames;
To bind a datacollection it is often easiest to use an ObservableCollection (if the data is changing runtime). When you do the binding you have to define a datacontext, a datasoure and a datapath. I will advice you to read some more about binding on MSDN :D
This will work for you -
MessageBox.Show(((sender as Button).DataContext as UserNames).UserName);
I am using a ToggleButton in a WPF window:
<ToggleButton Height="37"
HorizontalAlignment="Left"
Margin="485.738,254.419,0,0"
VerticalAlignment="Top"
Width="109"
IsEnabled="True"
Checked="toggleAPDTimeoutErr_Checked"
Unchecked="toggleAPDTimeoutErr_Unchecked">Timeout</ToggleButton>
I have two events that I am monitoring, but this is done in two different code behind handlers. How can this be done in only one?
I will have many ToggleButtons, and the code can get large.
You can attach a single click event of your ToggleButton and in its handler you can check the ToggleButton IsChecked property by type casting the sender object in your handler like this -
private void ToggleButton_Click(object sender, RoutedEventArgs e)
{
if((sender as ToggleButton).IsChecked)
{
// Code for Checked state
}
else
{
// Code for Un-Checked state
}
}
Xaml:
<ToggleButton Height="37" HorizontalAlignment="Left" Margin="485.738,254.419,0,0" VerticalAlignment="Top" Width="109" IsEnabled="True" Click="ToggleButton_Click">Timeout</ToggleButton>
You should not use Click event as some answers suggest, because it will not work when the property IsChecked is changed by code or any other event than mouse (keyboard, animation..). This is simply a bug.
Instead you can use the same handler for both Checked and Unchecked and do action depending on IsChecked property.
<ToggleButton
Checked="toggleButton_IsCheckedChanged"
Unchecked="toggleButton_IsCheckedChanged" />
Try this
private void tBtn_super_Click(object sender, RoutedEventArgs e)
{
if (tBtn_super.IsChecked == true)
{
MessageBox.Show("True");
}
else
{
MessageBox.Show("False");
}
}