C# 如何在C中更改组合框的itemsSource#

C# 如何在C中更改组合框的itemsSource#,c#,wpf,data-binding,combobox,C#,Wpf,Data Binding,Combobox,我正在尝试在运行时更改组合框的itemsource。在我被告知要做的事情中,comboBox.itemssource…。如果我只需要创建一个新的组合框,然后对其调用命令,那就可以了。但是,我需要通过xaml在用户控件中已经存在的组合框上执行此操作。在这种情况下,我将如何引用它?我知道如何绑定控件中的属性,但在这种情况下,我需要获取整个控件。我是不是想得太多了?做我想的事情的最好方法是什么 这是我当前在组合框中切换集合的方式(这都是在模型级别): //组合框列表的属性 公共ObservableCo

我正在尝试在运行时更改组合框的
itemsource
。在我被告知要做的事情中,
comboBox.itemssource…
。如果我只需要创建一个新的
组合框
,然后对其调用命令,那就可以了。但是,我需要通过xaml在用户控件中已经存在的
组合框上执行此操作。在这种情况下,我将如何引用它?我知道如何绑定控件中的属性,但在这种情况下,我需要获取整个控件。我是不是想得太多了?做我想的事情的最好方法是什么

这是我当前在组合框中切换集合的方式(这都是在模型级别):

//组合框列表的属性
公共ObservableCollection组合框列表
{
获取{return\u comboBoxList;}
设置
{
if(等于(值,_comboBoxList))返回;
_comboBoxList=值;
OnPropertyChanged(“ComboBoxList”);
}
}
公共字符串SelectedCommand
{
获取{return\u selectedCommand;}
设置
{
_selectedCommand=值;
NotifyPropertyChange(()=>SelectedCommand);
如果(SelectedCommand==“字符串值”)
{
ComboBoxList=新的ObservableCollection(新列表);
}
}
}
使用此实现时,集合会切换,但组合框
中的
selectedItem
不会粘住。例如,当我单击另一个命令,然后切换回时,框中不再有
selectedItem

更新

我有一个名为
selectedOperation
的属性,它绑定到我的
组合框
。它包含一个简单的getter和setter,带有一个
NotifyPropertyChange
。这使得框中的
selectedItem
保持选中状态。但是,如果用户单击不同的命令并在组合框中选择不同的项,则新项将取代它。我需要能够为组合框包含的每个集合设置一个
selectedItem

例如:

假设在
列表框中有两个命令,A和B。每个命令在
组合框中创建一个不同的集合。A创建一个数字集合,B创建一个名称集合

对于命令A,用户选择5。选择A时,
组合框
应按其
selectedItem
显示5。A->5

对于命令B,用户选择罗杰。当选择B时,
组合框
应显示“罗杰”,因为它是
selectedItem
。B->罗杰


当前,当用户在命令之间切换时,
comboBox
不记得它是
selectedItem

我宁愿使用
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.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"));
            }
        }
    }
}
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Windows;
命名空间WpfApplication10
{
公共部分类主窗口
{
公共主窗口()
{
初始化组件();
MyCustomCollection1=新的MyCustomCollection(新[]{“a”,“b”});
MyCustomCollection2=新的MyCustomCollection(新[]{“c”,“d”});
}
公共MyCustomCollection MyCustomCollection1{get;set;}
公共MyCustomCollection MyCustomCollection2{get;set;}
私有无效按钮\u单击(对象发送者,路由目标e)
{
DataContext=MyCustomCollection1;
}
私有无效按钮\u单击\u 1(对象发送者,路由目标)
{
DataContext=MyCustomCollection2;
}
}
公共类MyCustomCollection:ObservableCollection
{
私人T_mySelectedItem;
公共MyCustomCollection(IEnumerable集合):基本(集合)
{
}
公共选举
{
获取{return\u mySelectedItem;}
设置
{
如果(等于(值,_mySelectedItem))返回;
_mySelectedItem=值;
OnPropertyChanged(新PropertyChangedEventArgs(“MySelectedItem”);
}
}
}
}

尝试使用一些触发器(可以是任何触发器数据/事件)通过样式更改集合。以下是一个示例:

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


看起来您正在清除集合中的内容,然后添加新集合。即使在放置新列表时,这是否能够将所选项目存储在数据中?我已经用一些代码更新了我的答案,向您展示了如何用新的集合替换集合,基本上您只需要为它实现INotifyPropertyChanged。我喜欢这个答案,然而,在使用它的过程中,我还遇到了一个问题。请检查我的问题。不确定您在SelectedCommand中尝试执行的操作。。。无论如何,如果希望选中所选项目,则需要跟踪该项目。如果您想得到更好的答案,请提供您(通常)试图完成的任务的更多详细信息。我在
SelectedCommand
中,因为
组合框中的集合会根据
列表框中选择的命令而变化。我更新了我的问题以进一步解释。请看一看。
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));
        }
    }
}
<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"));
            }
        }
    }
}
<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>