Silverlight ListBox - Change When Selected State Occurs - silverlight

I have a ListBox that is used as a navigation menu. When an item is selected, it has a state that is highlighted. I have now implemented a message box when navigating away from a page if there are unsaved changes. The problem is, the visual state of the ListBoxItem is changed to selected upon click. I need to be able to change set the state to selected from code, instead of on click.
Is there a way to override the click event so that it doesn't cause the ListBoxItem to go to the selected state? I could then do VisualStateManager.GoToState(item, "Selected", true).
If not, is there a way to create a custom visual state for the ListBoxItem?

You should interrupt routing of MouseLeftButtonDown event from your item container and set selected item from view model. For instance:
XAML
<ListBox x:Name="lb">
<ListBoxItem>
<TextBlock MouseLeftButtonDown="TextBlock_OnMouseLeftButtonDown" Text="Test"/>
</ListBoxItem>
</ListBox>
Event Handler
private void TextBlock_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//interrups item selection
e.Handled = true;
//here you can show "Do you want navigate from?" dialog
// and if user accepts then show selected item in menu using SelectedItem or SelectedIndex
lb.SelectedIndex = 0;
}

Related

WPF ComboBox SelectionChanged event firing twice

In my DataGrid I am using DataGridComboBoxColumn as follows. Its SelectionChanged event (defined below) always fires twice - once when I click on an item, and then again when I select the new item from the dropdown. When I click on the item that I want to change the SelectionChanged event fires and shows the old value, and then when I select on a new value it fires again and correctly show the new value. But I want the event to be fired only when I select a new value for the combobox.
Question: What is causing this behavior and how can the issue be fixed?
Remark: Many users online seem to have similar issues posted here but none of them helped resolve my issue - maybe, the context is a bit different here. Moreover, the XAML and the code seem ok as it correctly displays the combobox values along with the correctly combox selected values for each row in the grid. Plus, the SelectionChanged event does correctly show the newly selected value but when it fires the second time. Similar code is shown here.
<DataGridComboBoxColumn Header="StartTime" SelectedItemBinding="{Binding localTime}" ItemsSource="{StaticResource localTimeList}">
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<EventSetter Event="SelectionChanged" Handler="MyComboBoxColumn_SelectionChanged"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
The event:
private void MyComboBoxColumn_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
var selectedVal = comboBox.SelectedValue.ToString();
}
What is causing this behavior?
The SelectionChanged event is raised initially when you enter the edit mode and the SelectedItem property is being bound to your source property.
How can the issue be fixed?
The easiest way to handle this is to check whether the ComboBox has been loaded and simply return from the event handler immediately if it hasn't:
private void MyComboBoxColumn_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
if (!comboBox.IsLoaded)
return;
//handle an actual selection here...
}

WPF - Detect Explicit Tab Selection vs. programmatic Tab Selection

I have an application where I would like to explicitly set focus to particular content inside of TabItem Content, dependent on whether the user clicked the tab explicitly or whether the tab was activated via code by setting hte SelectedIndex. Specifically I don't want to set focus to the embedded document content when programmatically selected (as I can explicitly force it via code), but I do want to set it when activated via Tab header click.
I haven't been able to effectively intercept the tab header click operation. Tab and tab content container clicks don't seem to fire and inside of the SelectedIndex_Changed event there's no indication where the activation originated from.
Any ideas what I can look at to determine explicit manual vs. programmatic tab activation?
I had a solution for this. You can capture mouse click event on tab header and set a bool flag. Then check the same flag in 'SelectionChanged' event of tab control, you can do what you want here such setting focus, then reset the flag to identify further clicks. Here is the sample code.
<TabControl SelectionChanged="TabControl_SelectionChanged">
<TabItem>
<TabItem.Header>
<TextBlock Text="ABC" MouseDown="TextBlock_MouseDown"/>
</TabItem.Header>
<!--<TabItem.InputBindings>
<MouseBinding Gesture="LeftClick" />
</TabItem.InputBindings>-->
</TabItem>
<TabItem Header="XYZ" />
</TabControl>
In code behind you can check like this
private void TabControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if(isClicked)
{
//you can set focus here
isClicked = false;
}
}
private void TextBlock_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
isClicked = true;
}
You can also try input bindings for tab item to detect the mouse click and raise the command, if you want to set the variable or take any required action. This way will be useful if you are following MVVM

How to use the context menu of the parent in a textbox

I have a listbox with several controls. Each control contains an custom autocompletebox which contains a System.Windows.Controls.AutoCompleteBox. When I right click on the control a custom contextm menu shows up. But with a right click on the textbox there appears the default contextmenu of the TextBox (with Copy, Cut and Paste).
My goal is to show my custom context menu with a right click on the TextBox.
Further informations:
My custom context menu is defined in the DataTemplate of the ListBox but I could define it in the Ressources or somewhere else as well.
I tried:
- when I null the context menu of the custom autocompletebox or the System.Windows.Controls.AutoCompleteBox of it, there is no effect at all
Thanks for every help ;)
You can either bind the context menu property to parent element's context menu or bind to the context menu once you define in the resource.xaml
Try using PreviewMouseDown instead of MouseDown to handle the MouseDown event.
In XAML:
<ListBox Margin="3" PreviewMouseDown="MouseDownOnListBox">
In Code:
private void MouseDownOnListBox(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Right)
{
//Display your context menu
}
}
If you are using PreviewMouseDown on a list, when you click anywhere on the list, this event will be triggered first.

WPF how to force menu item bindings to update when menu opens

I have a value that can change that doesn't raise a change event and the menu item bound to the value doesn't correctly reflect the state when the menu item is opened. I'd like to update this binding when the menu opens. How do I do this?
Can I have a menu item that just polls it's bindings each time the menu is opened? In this case the IsCommEnabled property:
<MenuItem Header="{Binding EnableComm}"
Command="{Binding Root.ToggleCommunications}"
IsChecked="{Binding Authorization.IsCommEnabled, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
--
public bool IsCommEnabled {
get { return _communications.IsCommEnabled; }
}
You can subscribe to the SubmenuOpened event, and manually update the binding:
void MenuItem_SubmenuOpened(object sender, RoutedEventArgs e)
{
((MenuItem)sender).GetBindingExpression(MenuItem.IsCheckedProperty).UpdateTarget();
}
Please note that the above applies to the Parent item being opened, so you may need to wrangle it a bit to ensure that it is the right item that is getting updated. You can use the Items collection on the MenuItem to dig deeper.
You have to raise NotifyPropertyChanged if you want to push the IsCommEnabled back to the bound Dependency Property

How to pass selected radio button in the next window and show that as selected in WPF?

I have a WPF Window with a datagrid dgSample. it has been bound to a list lstSample like this:
dgSample.itemssource=lstSample;
this datagrid also has a radio button column wherein i select one row by clicking on the radio button, and then, i can move to the next page after i click on the next button. On the next page, there is again the same datagrid, with the same radiobutton column. What I want is, that when i reach this page, i want the radio button that was selected in the previous page to be selected here as well.
I have tried binding the radiobutton column with an IsSelected Property by doing:
IsChecked="{Binding Path IsSelected, Mode=TwoWay}"
but this is not working.
What can I do to make it work?
P.S.: I prefer code-behind solution than the xaml one.
Please help !
Your model needs to implement INotifyPropertyChanged and call
PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"))
to get it to update in another view.
NB: If you set
public event PropertyChangedEventHandler PropertyChanged = delegate { };
you won't have to check for null.

Resources