2

在我的 Xaml 我有这个,

<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 但我尝试了那个,但它仍然没有更新。有谁知道为什么?

4

4 回答 4

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");
  }
}
于 2013-03-19T09:36:40.960 回答
2

我复制了你所有的代码,并在一个新的 WPF 应用程序中运行它。

为了解决您的绑定问题,有两种方法:

第一:在主窗口上创建一个 Loaded 事件,代码如下:

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

这在我的应用程序中提供了以下内容:

应用程序的图片

第二:您也可以像这样在 XAML 中绑定它:

在您的 MainWindow.xaml 中:

将以下内容添加到窗口标签:

DataContext="{绑定RelativeSource={RelativeSource Self}}"

然后在您的构造函数中,确保在 InitializeComponent() 运行之前设置数据:

public MainWindow()
{
   populateActionList();
   InitializeComponent();
}
于 2013-03-19T09:44:53.713 回答
2

在您的情况下,您也可以根据需要使用列表,因为您要替换整个列表而不是添加/删除单个项目。为此,您必须使用 ObservableCollection,就像 Jehof 所写的那样,当对集合执行添加/删除/清除/替换操作时,它会自动触发 CollectionChanged 事件(而不是PropertyChanged)。

您需要更改两件事才能使您的代码正常工作:

  1. 在您的视图模型中正确实现 INotifyPropertyChanged。对于您数据绑定的每个属性,您需要在 setter 中触发 PropertyChanged 事件。请参阅下面的代码。
  2. 当您想要更新绑定时,不要更改您的私有actionList字段,而是更改您的属性,因为当您更改字段时,不会触发 PropertyChanged 事件。ActionList

要记住的是:您的 UI 会侦听其数据绑定到的属性的 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" };
    }
}
于 2013-03-19T10:12:31.960 回答
1

ActionList应该是ObservableCollection<string>

您应该将DataContext窗口设置为具有属性的对象ActionList

于 2013-03-19T08:59:51.480 回答