1

アプリケーションにはComboBox、アイテムのコレクションにバインドされている があります。ユーザーが から項目を選択できる場合がありますComboBoxが、選択された項目はまだ準備ができていない可能性があるため、ComboBox選択された項目は前に選択された項目 (またはコレクション内の他の項目) に戻る必要がありますが、現在のアプリケーションComboBoxでは常にアイテムを元に戻して通知プロパティの変更を呼び出した後に有効なアイテムを取得する代わりに、ユーザーから選択されたアイテム。

流れは、問題を示す単純化されたコードです。

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private List<Customer> _Customers = new List<Customer>();

    public List<string> CustomerNames
    {
        get
        {
            var list = new List<string>();
            foreach (var c in _Customers)
            {
                list.Add(c.Name);
            }
            return list; ;
        }
    }

    public string CustomerName
    {
        get
        {
            var customer = _Customers.Where(c => c.IsReady).FirstOrDefault();
            return customer.Name;
        }
        set
        {
            NotifyPropertyChanged("CustomerName");
        }
    }

    public MainWindow()
    {
        SetupCustomers();
        InitializeComponent();
        this.DataContext = this;
    }

    private void SetupCustomers()
    {
        _Customers.Add(new Customer("c1", true));
        _Customers.Add(new Customer("c2", false));
        _Customers.Add(new Customer("c3", false));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class Customer
{
    public Customer(string name, bool isReady)
    {
        this.Name = name;
        this.IsReady = isReady;
    }

    public bool IsReady { get; set; }

    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }
    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}    


<Window x:Class="TryComboboxReset.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">
<Grid>

    <ComboBox   Width="100"
                Height="25"
                ItemsSource="{Binding Path=CustomerNames, Mode=OneWay}"
                SelectedItem="{Binding Path=CustomerName, Mode=TwoWay}"/>

</Grid>

4

2 に答える 2

1

問題は UI スレッドでした。ディスパッチャを使用してこの問題を修正しました

 public partial class MainWindow : Window, INotifyPropertyChanged
{
    private ObservableCollection<Customer> _Customers =
        new ObservableCollection<Customer>();

    public ObservableCollection<Customer> CustomerNames
    {
        get
        {
            return _Customers;
        }
    }

    public Customer CustomerName
    {
        get
        {
            return _Customers.Where(c => c.IsReady == true).FirstOrDefault();
        }
        set
        {
            // Delay the revert
            Application.Current.Dispatcher.BeginInvoke(
                new Action(() => NotifyPropertyChanged("CustomerName")), DispatcherPriority.ContextIdle, null);
        }
    }

    public MainWindow()
    {
        SetupCustomers();
        InitializeComponent();
        this.DataContext = this;
    }

    private void SetupCustomers()
    {
        _Customers.Add(new Customer("c1", true));
        _Customers.Add(new Customer("c2", false));
        _Customers.Add(new Customer("c3", false));
        CustomerName = _Customers.Where(c => c.IsReady == true).FirstOrDefault();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class Customer
{
    public Customer(string name, bool isReady)
    {
        this.Name = name;
        this.IsReady = isReady;
    }

    public bool IsReady { get; set; }

    public string Name { get; set; }
}   

<ComboBox   Width="400"
            Height="25"
            ItemsSource="{Binding Path=CustomerNames}"
            SelectedValue="{Binding CustomerName,Mode=TwoWay}"    >
       <ComboBox.ItemTemplate>
             <DataTemplate>
                 <TextBlock Text="{Binding Name}"/>
             </DataTemplate>
        </ComboBox.ItemTemplate>
 </ComboBox>
于 2013-06-14T16:32:04.103 に答える