Я использую комбинированный список WPF и заметил проблему, когда в комбинированном окне не отображается правильное значение привязки после обновления источника привязки, в то время как сам источник находится в процессе обновления из привязки.
Я собрал простой пример, чтобы продемонстрировать это.В этом примере у меня есть комбинированный список, содержащий 4 элемента (строки «A», «B», «C» и «D»).Существует двусторонняя привязка между SelectedItem в комбинированном ящике со свойством в текстовом тексте данных с именем ComboSelectedItem .
Предполагаемая функциональность заключается в том, что если пользователь выбирает "A"," B "или" C "из выпадающего списка, тогда логика в текстовом тексте попытается сбросить выбор в выпадающем списке на" D ".Однако вместо этого происходит следующее: если пользователь выбирает «A» в выпадающем списке, выбор остается на «A».
Вот пример кода ниже:
MainWindow.xaml:
<Window x:Class="Testing.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Margin="10,10,10,10">Combobox test:</Label>
<ComboBox Grid.Row="0" Grid.Column="1" Margin="10,10,10,10" x:Name="comboBox"
ItemsSource="{Binding Path=ComboBoxItems}" Width="80"
SelectedItem="{Binding Path=ComboSelectedItem, Mode=TwoWay}"/>
</Grid>
</Window>
и код для него:
using System;
using System.Windows;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using System.Windows.Threading;
namespace Testing
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
}
private ObservableCollection<String> items;
public ObservableCollection<String> ComboBoxItems
{
get
{
if (items == null)
{
items = new ObservableCollection<string>();
items.Add("A");
items.Add("B");
items.Add("C");
items.Add("D");
}
return items;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private string comboSelectedItem;
public string ComboSelectedItem
{
get { return comboSelectedItem; }
set
{
comboSelectedItem = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("ComboSelectedItem"));
//if value != D, set to D
if (ComboSelectedItem != "D")
{
ComboSelectedItem = "D";
}
}
}
}
}
Я обнаружил, что если я поставлю в очередь набор ComboSelectedItem , чтобы это происходило в потоке пользовательского интерфейса, тогда это будет работать, например:
public string ComboSelectedItem
{
get { return comboSelectedItem; }
set
{
comboSelectedItem = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("ComboSelectedItem"));
//if value != D, set to D
if (ComboSelectedItem != "D")
{
ThreadPool.QueueUserWorkItem(delegate(Object theElement)
{
UIElement elem = (UIElement)theElement;
elem.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate()
{
ComboSelectedItem = "D";
});
}, comboBox);
}
}
}
Однако я не совсем уверен, почему это работает, и в любом случае я бы предпочел не делать этого для всех выпадающих списков в моем приложении, где такой сценарий может
Вместо этого есть ли в Combobox параметр / свойство или какой-либо другой метод, который решил бы эту проблему для меня?Спасибо.