Wpf 在组合框上选择编辑项
应用程序中有一个绑定到项目集合的组合框。在某些情况下,用户可以从Wpf 在组合框上选择编辑项,wpf,combobox,selecteditem,Wpf,Combobox,Selecteditem,应用程序中有一个绑定到项目集合的组合框。在某些情况下,用户可以从组合框中选择项目,但所选项目可能尚未准备就绪,因此组合框所选项目必须返回到上一个所选项目(或集合中的其他项目),但是在当前应用程序中,组合框始终显示从用户处选择的项目,而不是在设置并调用notify property change后检索有效项目 flow是一个简化的代码,它显示了这个问题 public partial class MainWindow : Window, INotifyPropertyChanged { pr
组合框
中选择项目,但所选项目可能尚未准备就绪,因此组合框
所选项目必须返回到上一个所选项目(或集合中的其他项目),但是在当前应用程序中,组合框
始终显示从用户处选择的项目,而不是在设置并调用notify property change后检索有效项目
flow是一个简化的代码,它显示了这个问题
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>
public分部类主窗口:窗口,INotifyPropertyChanged
{
私人列表_客户=新列表();
公共列表客户名称
{
得到
{
var list=新列表();
foreach(客户的var c)
{
列表。添加(c.名称);
}
退货清单;
}
}
公共字符串客户名称
{
得到
{
var customer=_Customers.Where(c=>c.IsReady.FirstOrDefault();
返回客户名称;
}
设置
{
NotifyPropertyChanged(“客户名称”);
}
}
公共主窗口()
{
设置客户();
初始化组件();
this.DataContext=this;
}
私人客户()
{
_添加(新客户(“c1”,真));
_添加(新客户(“c2”,假));
_添加(新客户(“c3”,假));
}
公共事件属性更改事件处理程序属性更改;
受保护的void NotifyPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共类客户
{
公共客户(字符串名称,bool isReady)
{
this.Name=Name;
this.IsReady=IsReady;
}
公共bool已就绪{get;set;}
公共字符串名称{get;set;}
公共覆盖布尔等于(对象对象对象)
{
返回基数等于(obj);
}
公共覆盖int GetHashCode()
{
返回base.GetHashCode();
}
}
您实际上没有在setter中设置所选客户名称的值,getter总是会返回它找到的第一个“就绪”客户名称 如果我正确理解了问题,您需要按照以下思路做更多的工作:
private string _customerName = null;
public string CustomerName
{
get
{
if(_customerName == null)
{
_customerName = _Customers.Where(c => c.IsReady).FirstOrDefault().Name;
}
return _customerName;
}
set
{
_customerName = value;
NotifyPropertyChanged("CustomerName");
}
}
实际上,您并没有在setter中设置所选客户名称的值,getter总是返回它找到的第一个“就绪”客户名称 如果我正确理解了问题,您需要按照以下思路做更多的工作:
private string _customerName = null;
public string CustomerName
{
get
{
if(_customerName == null)
{
_customerName = _Customers.Where(c => c.IsReady).FirstOrDefault().Name;
}
return _customerName;
}
set
{
_customerName = value;
NotifyPropertyChanged("CustomerName");
}
}
问题是UI线程,我使用dispatcher解决了这个问题
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>
public分部类主窗口:窗口,INotifyPropertyChanged
{
私人可观测收集客户=
新的可观察集合();
公共可观测集合客户名称
{
得到
{
退回客户;
}
}
公共客户名称
{
得到
{
return _Customers.Where(c=>c.IsReady==true).FirstOrDefault();
}
设置
{
//延迟恢复
Application.Current.Dispatcher.BeginInvoke(
新操作(()=>NotifyPropertyChanged(“CustomerName”)),DispatcherPriority.ContextIdle,null);
}
}
公共主窗口()
{
设置客户();
初始化组件();
this.DataContext=this;
}
私人客户()
{
_添加(新客户(“c1”,真));
_添加(新客户(“c2”,假));
_添加(新客户(“c3”,假));
CustomerName=_Customers.Where(c=>c.IsReady==true).FirstOrDefault();
}
公共事件属性更改事件处理程序属性更改;
受保护的void NotifyPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共类客户
{
公共客户(字符串名称,bool isReady)
{
this.Name=Name;
this.IsReady=IsReady;
}
公共bool已就绪{get;set;}
公共字符串名称{get;set;}
}
问题是UI线程,我使用dispatcher解决了这个问题
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>
public分部类主窗口:窗口,INotifyPropertyChanged
{
私人可观测收集客户=
新的可观察集合();
公共可观测集合客户名称
{
得到
{
退回客户;
}
}
公共客户名称
{
得到
{
return _Customers.Where(c=>c.IsReady==true).FirstOrDefault();
}
设置
{
//延迟恢复
Application.Current.Dispatcher.BeginInvoke(
新操作(()=>NotifyPropertyChanged(“CustomerName”)),DispatcherPriority.ContextIdle,null);
}
}
公共主窗口()
{
设置客户();
初始化组件();
this.DataContext=this;
}
私人客户()
{
_添加(新客户(“c1”,真));
_添加(新客户(“c2”,假));
_添加(新客户(“c3”,假));
CustomerName=_Customers.Where(c=>c.IsReady==true).FirstOrDefault();
}
公共事件属性更改事件处理程序属性更改;
受保护的void NotifyPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共类客户
{
公共客户(字符串名称,bool isReady)
{
这是我的名字=