【问题标题】:Items in a listbox updating erratically WPF列表框中的项目不规律地更新 WPF
【发布时间】:2017-07-08 03:36:34
【问题描述】:

我有一个简单的字符串列表,我希望在列表框中显示这些字符串,具体取决于按下按钮时是否选中了复选框。我的按钮监听器中有这个逻辑:

private void fileSavePerms_Click(object sender, RoutedEventArgs e)
{
    foreach (CheckBox checkbox in checkboxList)
    {
        if (checkbox.IsChecked == true && !permissionList.Contains(checkbox.Name))
        {
            permissionList.Add(checkbox.Name);
        }

        else if (checkbox.IsChecked == false && permissionList.Contains(checkbox.Name))
        {
            permissionList.Remove(checkbox.Name);
        }
    }
    permListBox.ItemsSource = permissionList;
}

据我所知,这就是您如何在按钮单击时进行非常简单的数据绑定。然而,列表框第一次按预期更新,但随后将更新为我试图填充框的列表的不正确内容。我在输出中看不到明显的模式。

此外,一段时间后(单击几下按钮),我会捕获一个异常,说“an ItemsControl is inconsistent with its items source”。

我是否错误地设置了绑定或在错误的时间分配了ItemsControl

更新:

列表框的 XAML:

<ListBox x:Name="permListBox" ItemsSource="{Binding permissionList}" HorizontalAlignment="Left" Height="36" Margin="28,512,0,0" VerticalAlignment="Top" Width="442"/>

【问题讨论】:

  • 你能不能也分享一下这个列表框对应的XAML?
  • @DaveS 我已经为列表框添加了 XAML,谢谢

标签: c# wpf data-binding listbox itemssource


【解决方案1】:

首先,您只能将属性绑定到控件。不能绑定字段。所以permissionList 必须是您设置为Window.DataContext 属性的DataContext 对象的属性。

如果设置正确,那么您可以每次创建一个新的List<string>,然后将其分配给绑定到控件的属性。您不必将其分配给控件的ItemsSource 属性

假设您的窗口的数据上下文设置为窗口本身。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        this.DataContext = this;
    }

    public List<string> PermissionList
    {
        get { return (List<string>)GetValue(PermissionListProperty); }
        set { SetValue(PermissionListProperty, value); }
    }

    public static readonly DependencyProperty PermissionListProperty =
        DependencyProperty.Register(
            "PermissionList",
            typeof(List<string>),
            typeof(MainWindow),
            new PropertyMetadata(new List<string>())
        );

    private void fileSavePerms_Click(object sender, RoutedEventArgs e)
    {
        // You create a new instance of List<string>
        var newPermissionList = new List<string>();

        // your foreach statement that fills this newPermissionList
        // ...

        // At the end you simply replace the property value with this new list
        PermissionList = newPermissionList;
    }
}

在 XAML 文件中,您将拥有:

<ListBox 
    ItemsSource="{Binding PermissionList}"
    HorizontalAlignment="Left"
    VerticalAlignment="Top"
    Margin="28,512,0,0"
    Height="36"
    Width="442"/>

当然这个解决方案可以改进。

  • 您可以使用System.Collections.ObjectModel.ObservableCollection&lt;string&gt; 类型,这样您就不必每次都创建List&lt;string&gt; 的新实例,但您可以清除列表并在foreach 语句中添加新项目。
  • 您可以使用具有此权限列表并实现INotifyPropertyChanged 接口的 ViewModel 类(例如 MainViewModel),然后将此类的实例设置为 WPF 窗口的 DataContext 属性。

【讨论】:

  • 非常感谢您,同时查看 DependencyPropertys 似乎是一个有用的工具。另外值得一提的是,对于您的上述解决方案,XAML 绑定必须设置为{Binding PermissionList}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-23
  • 2010-12-15
相关资源
最近更新 更多