I have a ComboBox with the ItemsSource data bound. This ComboBox also lis开发者_运维百科tens to the SelectionChanged event.
However, when the ItemsSource changes, the SelectionChanged event is raised. This happens only the when ItemsSource is a view.
Is there a way to have the SelectionChanged raised only when the user does it, not when the ItemsSource property changes?
If you do your data binding in code behind you can unsubscribe to the SelectionChanged while ItemsSource is being changed. See below sample code:
XAML:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel DataContextChanged="OnDataContextChanged">
<Button Content="Change items" Click="OnClick" />
<ComboBox Name="_cb" />
</StackPanel>
</Window>
Code behind:
public partial class Window1
{
public Window1()
{
InitializeComponent();
_cb.SelectionChanged += OnSelectionChanged;
DataContext = new VM();
}
private void OnClick(object sender, RoutedEventArgs e)
{
(DataContext as VM).UpdateItems();
}
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
VM vm = DataContext as VM;
if (vm != null)
{
_cb.ItemsSource = vm.Items;
vm.PropertyChanged += OnVMPropertyChanged;
}
else
{
_cb.ItemsSource = null;
}
}
void OnVMPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Items")
{
_cb.SelectionChanged -= OnSelectionChanged;
_cb.ItemsSource = (DataContext as VM).Items;
_cb.SelectionChanged += OnSelectionChanged;
}
}
}
public class VM : INotifyPropertyChanged
{
public VM()
{
UpdateItems();
}
public event PropertyChangedEventHandler PropertyChanged;
private List<string> _items = new List<string>();
public List<string> Items
{
get { return _items; }
set
{
_items = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Items"));
}
}
}
public void UpdateItems()
{
List<string> items = new List<string>();
for (int i = 0; i < 10; i++)
{
items.Add(_random.Next().ToString());
}
Items = items;
}
private static Random _random = new Random();
}
I found that method :
private void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(!ComboBox.IsDropDownOpen)
{
return;
}
///your code
}
精彩评论