2013-03-19 115 views
2

在我的XAML中我有這個,ListBox中不顯示綁定數據

<ComboBox x:Name="masterCB" HorizontalAlignment="Left" Margin="5,127,0,0" VerticalAlignment="Top" Width="106" Height="22" Background="White" ItemsSource="{Binding Masters}" FontSize="11" SelectedIndex="{Binding Action}"/> 
     <Label Content="Select Action:" HorizontalAlignment="Left" VerticalAlignment="Top" Height="26" Width="116" Margin="0,151,0,0" Background="{x:Null}" FontWeight="Bold"/> 

<ListBox x:Name="actionBox" HorizontalAlignment="Left" Height="250" VerticalAlignment="Top" Width="116" Margin="5,177,0,0" ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
      ItemsSource="{Binding ActionList}" AlternationCount="2" MouseDoubleClick="actionBox_DoubleClick"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Grid Background="{x:Null}"> 
         <TextBlock Text="{Binding}" TextTrimming="WordEllipsis" TextWrapping="Wrap" Height="40" FontSize="11" /> 
        </Grid> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
      <ListBox.ItemContainerStyle> 
       <Style TargetType="{x:Type ListBoxItem}"> 
        <Style.Triggers> 
         <Trigger Property="ItemsControl.AlternationIndex" Value="1"> 
          <Setter Property="Background" Value="Silver"/> 
         </Trigger> 
        </Style.Triggers> 
       </Style> 
      </ListBox.ItemContainerStyle> 

在我的數據類我有這個,

private List<String> actionList; 
public int Action 
    { 
     get{return this.action;} 
     set 
     { 
      action = value; 
      populateActionList(); 
     } 
    } 
public List<String> ActionList 
    { 
     get { return actionList; } 
     set { this.actionList = value; } 
    private void populateActionList() 
    { 
     if (this.action == 0) 
     { 
      actionList = new List<String> { 
     "Chinese", 
     "Indian", 
     "Malay", 
     "Indian", 
     }; 
     if (this.action == 1) 
     { 
      actionList = new List<String> { 
     "Dog", 
     "Cats", 
     "Pigs", 
     "Horses", 
     "Fish", 
     "Lion"}; 
     } 
    } 

當我做一個打印行,我的ActionList改變,但ListBox項目未設置爲我的actionList。只想知道爲什麼以及UI如何不更新?我讀過的地方,你將不得不改變到DataContext和ObservableCollections,但我試過這一個,它仍然不會更新。有誰知道爲什麼?

回答

3

你的代碼更改爲以下,會做你所期望的

private ObservableCollection<String> _actionList; 

public ObservableCollection<String> ActionList { 
    get { 
    if (_actionList == null) { 
     _actionList = new ObservableCollection<String>(); 
    } 

    return actionList; 
    } 
} 

private void populateActionList(){ 
    if (this.action == 0) { 
    ActionList.Clear(); 

    ActionList.Add("Chinese"); 
    ActionList.Add("Indian"); 
    ActionList.Add("Malay"); 
    ActionList.Add("Indian"); 
    } 

    if (this.action == 1){ 
    ActionList.Clear(); 

    ActionList.Add("Dog"); 
    ActionList.Add("Cats"); 
    ActionList.Add("Pigs"); 
    ActionList.Add("Horses"); 
    ActionList.Add("Fish"); 
    ActionList.Add("Lion"); 
    } 
} 
+0

嗨thx的答案,我終於明白我的代碼出了什麼問題。一旦我有足夠的代表,我會贊成。謝謝! – Sheep 2013-03-20 01:53:07

1

ActionList應該是ObservableCollection<string>

你應該設置你的窗口DataContext對象財產ActionList

+0

將其更改爲的ObservableCollection不解決他的問題。他替換了屬性ActionList的值,因此需要爲屬性ActionList引發PropertyChanged事件。 – Jehof 2013-03-19 09:13:17

+1

你的權利:-)另一種方法是替換現有集合的內容,而不是創建新的實例。 – 2013-03-19 09:20:28

+0

大家好,thx爲您的答覆,但如果我沒有錯,如果我使用ObservableCollection,它不是已經提高PropertyChanged事件的變化在其自己的屬性(即。行動清單)? – Sheep 2013-03-19 09:20:55

2

我複製了所有的代碼,並運行它在一個新的WPF應用程序中。

爲了解決您的結合的問題,有兩種方式:

1:做一個Loaded事件的主窗口中,用下面的代碼:

private void Window_Loaded(object sender, RoutedEventArgs e) 
{ 
    DataContext = this; 
    populateActionList(); 
} 

這給下面的我應用:

pic of app

第二:您還可以在XAML綁定這個像這樣:

在MainWindow.xaml:

添加下面的窗口標籤:

的DataContext = 「{綁定的RelativeSource = {自我的RelativeSource}}」

然後在你的構造,使確保您的InitializeComponent()運行之前設置您的數據:

public MainWindow() 
{ 
    populateActionList(); 
    InitializeComponent(); 
} 
+0

嗨thx的答案,但問題是,我沒有使用主窗口,而是一個數據類來存儲我的所有數據(即印度華人馬來文都存儲在這個類)。因此,我無法使用任何方法自動調用populateActionList()。 – Sheep 2013-03-20 01:44:32

+0

在這種情況下,Jehof的代碼應該可以工作。確保在代碼或xaml中設置數據上下文,否則當您將可觀察集合綁定到xaml時,它可能不會更新。使用ObservableCollection的原因是在收集/數據更改時引發Collection/PropertyChanged事件。 – uNople 2013-03-20 01:55:22

+0

thx您的回覆 – Sheep 2013-03-20 03:58:06

2

在你的情況,你也可以用列表,如果你想工作,因爲要更換整個列表,而不是添加/刪除單個項目。爲此,您將不得不使用ObservableCollection,如Jehof寫道的那樣,在集合上執行添加/刪除/清除/替換操作時,它會自動觸發CollectionChanged事件(而不是 PropertyChanged)。

你需要改變兩件事情讓你的代碼工作:

  1. 在你的視圖模型正確執行INotifyPropertyChanged。對於數據綁定的每個屬性,您需要觸發setter中的PropertyChanged事件。看到我的代碼如下。
  2. 當您想要更新綁定時,請勿更改您的私人actionList字段,而應更改屬性ActionList,因爲當您更改字段時,PropertyChanged事件不會被觸發。

要記住的是:您的用戶界面監聽PropertyChanged和CollectionChanged事件的屬性,它是數據綁定到。所以如果你的UI沒有更新,這些事件通常不會被解僱。

視圖模型:

public class ViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string propertyName) 
    { 
     if (this.PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    // Masters 
    private List<string> _masters = new List<string>() { "Actions 0", "Actions 1" }; 
    public List<string> Masters { get { return _masters; } set { _masters = value; OnPropertyChanged("Masters"); } } 

    // Action 
    private int action; 
    public int Action { get { return this.action; } set { action = value; PopulateActionList(); OnPropertyChanged("Action"); } } 

    // ActionList 
    private List<String> actionList; 
    public List<String> ActionList { get { return actionList; } set { this.actionList = value; OnPropertyChanged("ActionList"); } } 


    private void PopulateActionList() 
    { 
     if (this.action == 0) 
      this.ActionList = new List<String> { "Chinese", "Indian", "Malay", "Indian" }; 
     else if (this.action == 1) 
      this.ActionList = new List<String> { "Dog", "Cats", "Pigs", "Horses", "Fish", "Lion" }; 
    } 
} 
+0

謝謝!今天我學到了一件新事物。一旦我得到了足夠的代表,我會感到高興,但直到那時你纔有我的感激:) – Sheep 2013-03-20 01:52:11