【问题标题】:Binding not working properly with ListBox绑定无法与 ListBox 一起正常工作
【发布时间】:2015-12-22 23:45:07
【问题描述】:

我将自定义类(实现 INotifyPropertyChanged)的列表绑定到 ListBox。

当我将任何项目添加到列表时,列表框不会更新,但如果我滚动,列表框会更新。

班级

class MyClass : INotifyPropertyChanged
{
    private string name = string.Empty;
    public string Name { /* INotifyPropertyChanged */ }
}

房产

private List<MyClass> loaded;
public List<MyClass> Loaded { /* INorutyPropertyChanged */ }

列表框

<ListBox ItemsSource={Binding Loaded} />

如果我强制覆盖 List 属性,它可以正常工作:

Loaded = new List<MyClass>() { new MyClass { Name = "test"; } }

【问题讨论】:

  • 我投了反对票,因为问题信息不完整。在以下答案之一中,询问用户有关套接字的信息。

标签: c# wpf mvvm binding listbox


【解决方案1】:

更新到:

public ObservableCollection<MyClass> Loaded { get; private set; }

<ListBox ItemsSource={Binding Loaded, UpdateSourceTrigger=PropertyChanged} />

此外,您不需要将INotiftyPropertyChanged 用于您的Loaded 属性。如果绑定发生一次,并且数据源没有改变,那就没有必要了。

编辑:

这是一个工作示例。

MainWindow.xaml

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox Width="200" ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Value}"/>
                </DataTemplate>
            </ListBox.ItemTemplate> 
        </ListBox>
        <Button Width="100" Height="75" HorizontalAlignment="Right" Content="Add" Command="{Binding AddItem}"/>
    </Grid>
</Window>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new DataContext();
    }
}

DataContext.cs

namespace WpfApplication3
{
    public class DataContext
    {
        public ObservableCollection<Item> Items { get; private set; }
        public ICommand AddItem { get; private set; }

        public DataContext()
        {
            Items = new ObservableCollection<Item>
            {
                new Item
                {
                    Value = "test"
                }
            };
            AddItem = new RelayCommand(() =>
            {
                Items.Add(new Item
                {
                    Value = "new item"
                });
            }, () => true);
        }
    }

    public class Item
    {
        public string Value { get; set; }
    }
}

RelayCommand.cs

public class RelayCommand : ICommand
{
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    private Action methodToExecute;
    private Func<bool> canExecuteEvaluator;
    public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator)
    {
        this.methodToExecute = methodToExecute;
        this.canExecuteEvaluator = canExecuteEvaluator;
    }
    public RelayCommand(Action methodToExecute)
        : this(methodToExecute, null)
    {
    }
    public bool CanExecute(object parameter)
    {
        if (this.canExecuteEvaluator == null)
        {
            return true;
        }
        else
        {
            bool result = this.canExecuteEvaluator.Invoke();
            return result;
        }
    }
    public void Execute(object parameter)
    {
        this.methodToExecute.Invoke();
    }
}

如果您有任何问题,请告诉我。

【讨论】:

  • 我意识到问题是因为我使用的是异步 Socket 并且我收到有关线程安全的错误。 List 属性是在主线程上创建的,然后我调用 BeginAcceptSocket,当客户端连接时,它无法添加到 List
  • 啊,该死!太棒了,至少你找到了问题。
  • @hendoe 在你的问题中你没有提到。
猜你喜欢
  • 2016-09-27
  • 2019-10-31
  • 2012-06-21
  • 2020-08-02
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
相关资源
最近更新 更多