2013-10-04 32 views
2

我試圖在運行時更改comboBoxitemsSource。在this question我被告知要做,​​。如果我只需要創建一個新的comboBox然後調用它就可以了。但是,我需要在我的用戶控件中通過xaml存在的comboBox上執行此操作。在那種情況下,我會如何參考它?我知道如何綁定到控件的屬性,但在這種情況下,我需要獲得整個控件。我是否過度思考?什麼是最好的方式來做我在想什麼?如何更改C#中組合框的項目源碼

這個我目前如何切換集合在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); 
     } 
    } 
} 

館藏使用這個實現時切換,但在comboBoxselectedItem不沾。例如,當我點擊不同的命令然後切換回來時,該框不再有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 - > Roger

當前,comboBox不記得它是selectedItem當用戶之間切換命令。

回答

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

注:[CallerMemberName]節省你每次調用調用器時添加的屬性名稱,但如果我沒有記錯,這只是針對.NET 4.5。

如果你不在.NET 4.5下,那麼你必須改爲OnPropertyChanged("Collection")

參考:INotifyPropertyChanged

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

EDIT 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")); 
      } 
     } 
    } 
} 
+0

它看起來像你正在清除收藏集中的內容,然後添加新的收藏集。這將能夠存儲在數據中的選定項目,即使當一個新的列表放在它的位置 –

+0

我用一些代碼更新了我的答案,告訴你如何用新的代替集合,基本上你只需要實現INotifyPropertyChanged它。 – Aybe

+0

我喜歡這個答案,但是在使用它時遇到了另外一個問題。請結帳我的問題。 –

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> 
相關問題