我正在尝试在运行时更改itemsSource
的{{1}}。在this question我被告知要做comboBox
。如果我需要做的就是创建一个新的comboBox.itemssource...
,然后在其上调用命令,那就没关系。但是,我需要通过xaml在我的用户控件中已存在的comboBox
上执行此操作。在那种情况下,我将如何引用它?我知道如何绑定到控件中的属性,但在这种情况下,我需要获得整个控件。我是在过度思考吗?做我想的最好的方法是什么?
这是我目前如何在comboBox
中切换收藏集(这是模型级别的所有收藏):
comboBox
使用此实现时,集合会切换,但//Property for Combo Box List
public ObservableCollection<string> ComboBoxList
{
get { return _comboBoxList; }
set
{
if (Equals(value, _comboBoxList)) return;
_comboBoxList = value;
OnPropertyChanged("ComboBoxList");
}
}
public string SelectedCommand
{
get { return _selectedCommand; }
set
{
_selectedCommand = value;
NotifyPropertyChange(() => SelectedCommand);
if (SelectedCommand == "String Value")
{
ComboBoxList = new ObservableCollection<string>(newList);
}
}
}
中的selectedItem
不会停留。例如,当我单击其他命令然后切换回来时,该框不再具有comboBox
。
更新
我有一个名为selectedItem
的属性绑定到我的selectedOperation
。它包含一个简单的getter和setter,带有comboBox
。这使得框中的NotifyPropertyChange
保持选中状态。但是,如果用户点击其他命令并选择selectedItem
中的其他项目,则该新项目会将其取代。我需要为comboBox
拥有的每个集合设置selectedItem
。
例如:
假设comboBox
,A和B中有2个命令。每个命令在listBox
中创建一个不同的集合。 A创建一个数字集合,B创建一个名称集合。
对于命令A,用户选择5.当选择A时,comboBox
应显示5,因为它是comboBox
。 A - &gt; 5
对于命令B,用户选择Roger。选择B后,selectedItem
应显示“Roger”,因为它是comboBox
。 B - &gt;罗杰
目前,当用户在命令之间切换时,selectedItem
不记得comboBox
。
答案 0 :(得分:3)
我宁愿使用DataContext
并更新该来源,也不要手动更新ComboBox.ItemsSource
属性。
这样就根本不需要了解控件。
这是一个小例子:
当用户点击该按钮时,您只需要处理更新数据,而不是更新数据。
<Window x:Class="WpfApplication10.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" x:Name="Window1">
<Grid DataContext="{Binding ElementName=Window1}">
<StackPanel>
<Button Click="Button_Click">Some data 1</Button>
<Button Click="Button_Click_1">Some data 2</Button>
<ListBox x:Name="ComboBox1" ItemsSource="{Binding Collection}"></ListBox>
</StackPanel>
</Grid>
</Window>
using System.Collections.ObjectModel;
using System.Windows;
namespace WpfApplication10
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly ObservableCollection<string> _collection = new ObservableCollection<string>();
public MainWindow()
{
InitializeComponent();
}
public ObservableCollection<string> Collection
{
get { return _collection; }
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_collection.Clear();
for (int i = 0; i < 5; i++)
{
_collection.Add("method 1 item " + i);
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{ _collection.Clear();
for (int i = 0; i < 5; i++)
{
_collection.Add("method 2 item " + i);
}
}
}
}
<强>更新
如果您想使用新集合而不是删除项目,则必须为集合实现INotifyPropertyChanged。
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
namespace WpfApplication10
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
private ObservableCollection<string> _collection = new ObservableCollection<string>();
public MainWindow()
{
InitializeComponent();
}
public ObservableCollection<string> Collection
{
get { return _collection; }
set
{
if (Equals(value, _collection)) return;
_collection = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void Button_Click(object sender, RoutedEventArgs e)
{
Collection = new ObservableCollection<string>(new[] {"1", "2"});
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Collection = new ObservableCollection<string>(new[] {"3", "4"});
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
注意:每次调用invocator时,[CallerMemberName]
都会使您免于添加属性名称,但如果我没记错的话,它只能用于.NET 4.5。
如果您不在.NET 4.5之下,那么您必须改为OnPropertyChanged("Collection")
。
此外,使用新集合更新Collection
,而不是_collection
,否则您的用户界面将不会收到通知。
编辑2
您需要根据使用的集合跟踪所选项目。
<Window x:Class="WpfApplication10.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" x:Name="Window1">
<Grid>
<StackPanel>
<Button Click="Button_Click">Some data 1</Button>
<Button Click="Button_Click_1">Some data 2</Button>
<ListBox x:Name="ComboBox1" ItemsSource="{Binding}" SelectedItem="{Binding MySelectedItem}" />
</StackPanel>
</Grid>
</Window>
代码背后:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
namespace WpfApplication10
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
MyCustomCollection1 = new MyCustomCollection<string>(new[] {"a", "b"});
MyCustomCollection2 = new MyCustomCollection<string>(new[] {"c", "d"});
}
public MyCustomCollection<string> MyCustomCollection1 { get; set; }
public MyCustomCollection<string> MyCustomCollection2 { get; set; }
private void Button_Click(object sender, RoutedEventArgs e)
{
DataContext = MyCustomCollection1;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
DataContext = MyCustomCollection2;
}
}
public class MyCustomCollection<T> : ObservableCollection<T>
{
private T _mySelectedItem;
public MyCustomCollection(IEnumerable<T> collection) : base(collection)
{
}
public T MySelectedItem
{
get { return _mySelectedItem; }
set
{
if (Equals(value, _mySelectedItem))return;
_mySelectedItem = value;
OnPropertyChanged(new PropertyChangedEventArgs("MySelectedItem"));
}
}
}
}
答案 1 :(得分:0)
尝试使用一些触发器(可以是任何触发器数据/事件)通过样式更改集合这里是一个例子:
<Style x:Key="MySelectItemSourceStyle" TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding Collection1}" />
<Style.Triggers>
<DataTrigger Binding="{Binding SomeValue}" Value="SecondCollection">
<Setter Property="ItemsSource" Value="{Binding Collection2}" />
</DataTrigger>
</Style.Triggers>
</Style>