[英]How to bind one ObservableCollection as ItemsSource to different comboBoxes (models) if using wpf ItemsControl with MVVM pattern?
I dynamically create a list of comboBoxes to different Models using wpf ItemsControl element using MVVM pattern. 我使用MVVM模式使用wpf ItemsControl元素动态创建到不同模型的comboBoxes列表。 I want to have a logic like if i select an element in one of the comboBoxes, then in all the others it will not appear. 我想要一种逻辑,例如,如果我在comboBoxes之一中选择一个元素,那么在所有其他元素中它都不会出现。 I have difficulty with that when i use ItemsControl (ItemsSource - list of my Models) and create elements for it in VievModel - binding is not working, it works only when i have a comboBox items list for each of Models (Model class), not for all comboBoxes (in ViewModel class). 我在使用ItemsControl(ItemsSource-我的模型的列表)并在VievModel中为其创建元素时遇到困难-绑定不起作用,仅当我为每个模型(Model类)有一个comboBox项目列表时,它才起作用适用于所有comboBoxes(在ViewModel类中)。 Can i have, for example, 1 ObservableCollection for comboBox items in ViewModel and use also ItemsControl to create comboBoxes? 例如,我可以为ViewModel中的comboBox项提供1个ObservableCollection,还可以使用ItemsControl创建comboBoxes吗?
My View : 我的观点 :
<ItemsControl ItemsSource="{Binding Items}" Grid.Row="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Name}" Grid.Column="0" />
<ComboBox ItemsSource="{Binding ComboBoxItems}" Grid.Column="1"
SelectedItem="{Binding SelectedItem}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ViewModel: ViewModel:
public ObservableCollection<Model> Items { get; set; }
// if I add here public ObservableCollection<string> ComboBoxItems { get; set; }
// binding isn't working, so I add it to Model class, but in it it does not work as I need.
public ViewModel()
{
Items = new ObservableCollection<Model>();
Items.Add(new Model {Name = "11111"});
Items.Add(new Model {Name = "22222"});
}
Model: 模型:
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
public string SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
public ObservableCollection<string> ComboBoxItems {get;set;}
public Model()
{
ComboBoxItems = new ObservableCollection<string>();
ComboBoxItems.Add("q");
ComboBoxItems.Add("w");
ComboBoxItems.Add("e");
ComboBoxItems.Add("r");
ComboBoxItems.Add("t");
ComboBoxItems.Add("y");
}
1 ObservableCollection for comboBox items in ViewModel and use also ItemsControl to create comboBoxes This means u wanna bind the same ObservableCollection to ur ItemsControl
and ComboBox
if not please let me know in comment 1个ViewModel中的comboBox项的ObservableCollection,还可以使用ItemsControl来创建comboBoxes,这意味着您想将相同的ObservableCollection绑定到ur ItemsControl
和ComboBox
,否则请在评论中告知我
Ans 安斯
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding Name}" Grid.Column="0" />
<ComboBox ItemsSource="{Binding Items ,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ItemsControl}}" Grid.Column="1"
DisplayMemberPath="Name" SelectedItem="{Binding SelectedItem}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
i Binded Items
to ComboBox
我将Items
绑定到ComboBox
In order to achieve your goal, you can filter view of ComboBoxItems
. 为了实现您的目标,您可以过滤ComboBoxItems
视图。 You can do it in single source single view way, which you only need to change your ViewModel
's constructor like: 您可以以单源单视图的方式进行操作,只需更改ViewModel
的构造函数,例如:
public ViewModel()
{
Items = new ObservableCollection<Model>();
Items.Add(new Model {Name = "11111"});
Items.Add(new Model {Name = "22222"});
Items.Add(new Model {Name = "33333"});
foreach (var item in Items)
{
CollectionViewSource.GetDefaultView(item.ComboBoxItems).Filter =
(x) => !Items.Where((y) => y != item).Select(y => y.SelectedItem).Any(y => y == (string)x);
item.PropertyChanged += (s, e) =>
{
foreach (var obj in Items.Where((x) => x != item).Select(x => x.ComboBoxItems))
CollectionViewSource.GetDefaultView(obj).Refresh();
};
}
}
Or you can also do it in single source multiple view way, which allow you discard your model. 或者,您也可以单源多视图的方式进行操作,从而可以丢弃模型。
public class ViewModel
{
private List<string> _comboBoxItems = new List<string> { "q", "w", "e", "r", "t", "y" };
private List<ICollectionView> _comboBoxViews = new List<ICollectionView>();
public ObservableCollection<string> Names { get; set; } = new ObservableCollection<string> { "111", "222", "333" };
public ICollectionView ComboBoxView
{
get
{
var view = new CollectionViewSource { Source = _comboBoxItems}.View;
_comboBoxViews.Add(view);
view.MoveCurrentToPosition(-1);
view.Filter = (x) => !_comboBoxViews.Where(y => y != view).Any(y => (string)y.CurrentItem == (string)x);
view.CurrentChanged += (s, e) =>
{
foreach (var v in _comboBoxViews.Where(x => x != view))
v.Refresh();
};
return view;
}
}
}
<ItemsControl ItemsSource="{Binding Names}" Grid.Row="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding}" Grid.Column="0" />
<ComboBox ItemsSource="{Binding DataContext.ComboBoxView, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
Grid.Column="1"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.