ComboBox上的SelectedItem [英] SelectedItem on ComboBox

查看:114
本文介绍了ComboBox上的SelectedItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在应用程序中绑定了一组项目的 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;组; }

public string Name {get;组; }

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 =MainWindowHeight =350Width = 525>
< Grid>

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

< / Grid>

解决方案>

问题是UI线程,我使用dispatcher来解决这个问题。

  public partial 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
{
//延迟还原
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。名称=名称;
this.IsReady = isReady;
}

public bool IsReady {get;组; }

public string Name {get;组; }
}

< 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>


There is a ComboBox in the application which is bound to a collection of items. There are cases that user can select an item from the ComboBox but the selected item might not be ready yet so the ComboBox selected item must get back to the previous selected item (or some other item in the collection), but in the current application ComboBox always shows the selected item from the user instead of retrieving the valid item after setting it back and calling notify property change.

The flowing is a simplified code of which shows the problem.

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>

解决方案

The problem was UI thread, I used dispatcher to fix this problem

 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>

这篇关于ComboBox上的SelectedItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆