c# - 绑定(bind)到 List<string> 不更新相应的字符串

标签 c# wpf data-binding

我有以下 XAML 代码:

<Window x:Class="WpfApplication1.MainWindow"
        x:Name="window"
        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"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="327" Width="213" 
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>          
        <ListBox ItemsSource="{Binding Strings}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Path=., UpdateSourceTrigger=PropertyChanged}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <TextBox Grid.Row="1" Text="{Binding TheString}" />
        <Button Click="ButtonBase_OnClick" Grid.Row="2">Check strings</Button>
    </Grid>
</Window>

非常简单。现在这是我的代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
    }

    public List<string> Strings { get; } = new List<string> { "Hello world1", "Hello world2", "Hello world3" };

    public string TheString { get; set; } = "Helloo";

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(string.Join("\n", this.Strings) + $"\n\n{this.TheString}");
    }
}

问题是,如果我从 UI 更新 Strings 列表中的字符串值,当我单击按钮时它永远不会更新。我做错了什么?
我正确地将 ListboxItemsSource 绑定(bind)到 Strings 列表。我还正确绑定(bind)了 ItemTemplate 中的 TextBox

最佳答案

您遇到的问题是关于字符串的不变性。当您更改 TextBox 中的文本时,您会创建一个新的字符串,旧字符串不会更改。因此列表始终包含相同的值。

要更新它,您应该将其包装在一个实现 INotifyPropertyChanged 的​​类中,并在 setter 中触发 PropertyChanged 事件。您还应该更改对此新属性的绑定(bind)。例如:

public class Wrapper : INotifyPropertyChanged
{
    private string _value;
    public string Value
    {
        get { return _value; }
        set
        {
            _value = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
        }
    }

    //INotifyPropertyChanged implementation...
}

您的列表应该是:

public List<MyClass> Strings { get; } = new List<MyClass>
{
    new Wrapper { Value = "Hello world1" },
    new Wrapper { Value = "Hello world2" },
    new Wrapper { Value = "Hello world3" }
};

绑定(bind)应该是:

<TextBox Text="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}" />

关于c# - 绑定(bind)到 List<string> 不更新相应的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36071766/

相关文章:

c# - 从对象获取属性信息而不将属性名称作为字符串提供

c# - 在 ModalDialog 窗口中只显示垂直滚动条?

wpf - 如何使用 LinearGradientBrush 和背景

wpf - 如何使用 Trigger 检查 DataGridColumnHeader 的 ColumnIndex 是否是最后一个?

c# - 将 List<T> 中的数据绑定(bind)到 DatagridView

javascript - Polymer 对象的属性不从 setInterval 方法内部触发绑定(bind)

c# - 使用具有强类型方法的类型对象

c# - 我如何将此文本与正则表达式匹配?

WPF 效果 - 对文本

grails - Grails:JSON到bean-自定义字段名称