如何防止用户从wpf中的多个组合框中选择相同的值
我有一个简单的类:如何防止用户从wpf中的多个组合框中选择相同的值,wpf,combobox,Wpf,Combobox,我有一个简单的类: public class Item { public int ID{get;set;} public string Name{get;set;} } public List<Item> AllItems=GetAllItems(); public Item Item1{get;set;} public Item Item2{get;set;} public Item Item3{get;set;} public Item Item4{get;set
public class Item
{
public int ID{get;set;}
public string Name{get;set;}
}
public List<Item> AllItems=GetAllItems();
public Item Item1{get;set;}
public Item Item2{get;set;}
public Item Item3{get;set;}
public Item Item4{get;set;}
<TextBlock x:Name="txtName1" Text="{Binding Item1.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName2" Text="{Binding Item2.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName3" Text="{Binding Item3.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName4" Text="{Binding Item4.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
我在Mainwindow.xaml.cs中有一个此类列表,如下所示:
public class Item
{
public int ID{get;set;}
public string Name{get;set;}
}
public List<Item> AllItems=GetAllItems();
public Item Item1{get;set;}
public Item Item2{get;set;}
public Item Item3{get;set;}
public Item Item4{get;set;}
<TextBlock x:Name="txtName1" Text="{Binding Item1.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName2" Text="{Binding Item2.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName3" Text="{Binding Item3.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName4" Text="{Binding Item4.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
此列表:AllItems数据绑定到四个组合框,如下所示:
<ComboBox x:Name="cmbCode1" ItemsSource="{Binding AllItems}" DisplayMemberPath="ID" SelectedValuePath="ID" SelectedValue="{Binding Item1.ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Item1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox x:Name="cmbCode2" ItemsSource="{Binding AllItems}" DisplayMemberPath="ID" SelectedValuePath="ID" SelectedValue="{Binding Item1.ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Item1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox x:Name="cmbCode3" ItemsSource="{Binding AllItems}" DisplayMemberPath="ID" SelectedValuePath="ID" SelectedValue="{Binding Item1.ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Item1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox x:Name="cmbCode4" ItemsSource="{Binding AllItems}" DisplayMemberPath="ID" SelectedValuePath="ID" SelectedValue="{Binding Item1.ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Item1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
我有四个文本框对应这四个组合框:
public class Item
{
public int ID{get;set;}
public string Name{get;set;}
}
public List<Item> AllItems=GetAllItems();
public Item Item1{get;set;}
public Item Item2{get;set;}
public Item Item3{get;set;}
public Item Item4{get;set;}
<TextBlock x:Name="txtName1" Text="{Binding Item1.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName2" Text="{Binding Item2.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName3" Text="{Binding Item3.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName4" Text="{Binding Item4.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
我想要的是,用户永远不能从多个组合框中选择相同的ID。
是否有一些简单的方法可以做到这一点,特别是仅使用xaml?如何隐藏或显示从其他组合框中选择/未选择的项目,以便用户无法从多个组合框中选择相同的ID?
到目前为止,我已尝试将所选项目和整个列表发送到多值转换器,并将项目删除/添加到列表中,但这似乎过于简单。如果有其他更好的想法,我们将不胜感激。您可以为每个组合框创建单独的列表。然后,您可以向它们中的每一个添加一个事件处理程序。您可以使用它来重新填充其他组合框的列表,以排除选择 例如,如果我的列表中有5项;最初,我可以在任何组合框中选择全部5个。当我在ComboBox 1中选择Item1时,LostFocus事件处理程序将更新ComboBox 2-4后面的列表以删除Item1。然后,当我在ComboBox 2中选择Item2时,LostFocus事件处理程序将更新ComboBox 3和4后面的列表以删除Item2。等等 另一种方法可能是让用户选择他们喜欢的任何内容,然后对所选值进行某种验证,以确保它们是唯一的。这是你的一些选择
就我个人而言,我会选择第二种方法;可能在文本框上方有一条消息,指示所选内容必须是唯一的。当选择无效时,您可以指示任何错误并阻止依赖该选择的任何操作,但您不必不断更新数据,这可能会导致更平滑的用户界面。您可以使用该代码在不同的组合框中隐藏所选项
for (int count = 0; count <= cmb1.Items.Count -1; count++)
{
if((ComboBoxItem)(cmb1.Items[count])).SelectedValue==TextBox1.Text)
((ComboBoxItem)(cmb1.Items[count])).Visibility = System.Windows.Visibility.Collapsed;
}
for(int-count=0;count您应该在视图模型中处理这种逻辑。下面是一个示例,可以让您了解:
查看模型:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
AllItems = new List<Item>() { new Item { Name = "1" }, new Item { Name = "2" }, new Item { Name = "3" }, new Item { Name = "4" } };
}
public List<Item> AllItems { get; set; }
private Item _item1;
public Item Item1
{
get { return _item1; }
set
{
_item1 = value;
NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
private Item _item2;
public Item Item2
{
get { return _item2; }
set
{
_item2 = value;
NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
private Item _item3;
public Item Item3
{
get { return _item3; }
set
{
_item3 = value; NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
private Item _item4;
public Item Item4
{
get { return _item4; }
set
{
_item4 = value;
NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Item : INotifyPropertyChanged
{
public int ID { get; set; }
public string Name { get; set; }
private bool _canSelect = true;
public bool CanSelect
{
get { return _canSelect; }
set { _canSelect = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
<Style x:Key="icstyle" TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding CanSelect}" />
</Style>
...
<ComboBox x:Name="cmbCode1" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item1}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
<ComboBox x:Name="cmbCode2" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item2}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
<ComboBox x:Name="cmbCode3" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item3}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
<ComboBox x:Name="cmbCode4" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item4}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
public分部类主窗口:窗口,INotifyPropertyChanged
{
公共主窗口()
{
初始化组件();
DataContext=this;
AllItems=new List(){new Item{Name=“1”},new Item{Name=“2”},new Item{Name=“3”},new Item{Name=“4”};
}
公共列表所有项{get;set;}
私人物品_item1;
公共项目1
{
获取{return\u item1;}
设置
{
_第1项=价值;
NotifyPropertyChanged();
if(值!=null)
value.CanSelect=false;
}
}
私人物品_物品2;
公共项目2
{
获取{return\u item2;}
设置
{
_第2项=价值;
NotifyPropertyChanged();
if(值!=null)
value.CanSelect=false;
}
}
私人项目_项目3;
公共项目3
{
获取{return\u item3;}
设置
{
_item3=值;NotifyPropertyChanged();
if(值!=null)
value.CanSelect=false;
}
}
私人项目_项目4;
公共项目4
{
获取{return\u item4;}
设置
{
_第4项=价值;
NotifyPropertyChanged();
if(值!=null)
value.CanSelect=false;
}
}
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged([CallerMemberName]字符串propertyName=”“)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共类项目:INotifyPropertyChanged
{
公共int ID{get;set;}
公共字符串名称{get;set;}
私有bool_canSelect=true;
公共图书馆可供选择
{
获取{return\u canSelect;}
设置{u canSelect=value;NotifyPropertyChanged();}
}
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged([CallerMemberName]字符串propertyName=”“)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
XAML:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
AllItems = new List<Item>() { new Item { Name = "1" }, new Item { Name = "2" }, new Item { Name = "3" }, new Item { Name = "4" } };
}
public List<Item> AllItems { get; set; }
private Item _item1;
public Item Item1
{
get { return _item1; }
set
{
_item1 = value;
NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
private Item _item2;
public Item Item2
{
get { return _item2; }
set
{
_item2 = value;
NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
private Item _item3;
public Item Item3
{
get { return _item3; }
set
{
_item3 = value; NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
private Item _item4;
public Item Item4
{
get { return _item4; }
set
{
_item4 = value;
NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Item : INotifyPropertyChanged
{
public int ID { get; set; }
public string Name { get; set; }
private bool _canSelect = true;
public bool CanSelect
{
get { return _canSelect; }
set { _canSelect = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
<Style x:Key="icstyle" TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding CanSelect}" />
</Style>
...
<ComboBox x:Name="cmbCode1" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item1}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
<ComboBox x:Name="cmbCode2" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item2}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
<ComboBox x:Name="cmbCode3" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item3}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
<ComboBox x:Name="cmbCode4" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item4}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
...
XAML是一种标记语言……它不是用来实现这种逻辑的。您应该使用编程语言来实现这一点。@mm8:由于我对WPF的了解有限,目前我正在使用多值转换器,在更改每个SelectedItem时,我发送的不是一个而是全部四个列表,并且正在执行所有的加分s到那里的列表..tx用于那里的更新。至少现在我不会花时间去想它是否可能在XAML中实现,我不知道..-)。。