2013-03-19 119 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