簡體   English   中英

如何在C#中更改ComboBox的itemsSource

[英]How to change the itemsSource of a ComboBox in C#

我正在嘗試在運行時更改comboBoxitemsSource 這個問題中,我被告知要做的是comboBox.itemssource... 如果我需要做的就是創建一個新的comboBox ,然后在其上調用命令,那將是可以的。 但是,我需要通過xaml在用戶控件中已經存在的comboBox上執行此操作。 在這種情況下,我將如何引用它? 我知道如何綁定到控件中的屬性,但是在這種情況下,我將需要獲取整個控件。 我是否在考慮過度? 做我在想什么的最好方法是什么?

這是我目前如何切換comboBox的Collections的方式(這全部在模型級別):

//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);
        }
    }
}

使用此實現時,集合會切換,但是comboBox中的selectedItem不會停留。 例如,當我單擊其他命令然后再切換回時,該框不再具有selectedItem

UPDATE

我有一個名為selectedOperation的屬性,該屬性綁定到我的comboBox 它包含一個簡單的getter和setter,以及一個NotifyPropertyChange 這樣可以使框中的selectedItem保持選中狀態。 但是,如果用戶單擊其他命令並在comboBox選擇其他項,則該新項將代替它。 我需要能夠為comboBox保存的每個集合都有一個selectedItem

例如:

假設listBox有2個命令,A和B。每個命令在comboBox創建一個不同的集合。 A創建一個數字集合,而B創建一個名稱集合。

對於命令A,用戶選擇5。當選擇A時, comboBox應顯示5作為selectedItem A-> 5

用戶為命令B選擇Roger。 選擇B時, comboBox應顯示“ Roger”作為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.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));
        }
    }
}

注意: [CallerMemberName][CallerMemberName]在每次調用[CallerMemberName]添加屬性名,但是如果我沒記錯的話,它僅適用於.NET 4.5。

如果您不在.NET 4.5下,則必須改用OnPropertyChanged("Collection")

參考: INotifyPropertyChanged

此外,更新Collection與一個新的集合,而不是_collection否則你的UI將不會收到通知。

編輯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"));
            }
        }
    }
}

嘗試使用一些觸發器(可以是任何觸發器數據/事件)通過樣式更改集合,這是一個示例:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM