【问题标题】:How to bind TextBoxes to an ObservableCollection in an ItemsControl with UniformGrid如何使用 UniformGrid 将 TextBoxes 绑定到 ItemsControl 中的 ObservableCollection
【发布时间】:2021-02-13 00:53:09
【问题描述】:

如果在 WPF 中我有这个代码:

using System.Collections.ObjectModel;

...
...

public partial class MainWindow : Window
{
    public ObservableCollection<String> myMatrixData = new ObservableCollection<String>();
    public MainWindow()
    {
        InitializeComponent();

        int i;
        for (i = 0; i < 100; i++)
            myMatrixData.Add("Test");

        myMatrix.ItemsSource = myMatrixData;
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        Cell00.Text = myMatrixData[0];
    }
}

XAML:

    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
...
...
<Grid>
    <StackPanel>
        <ItemsControl x:Name="myMatrix">
            <ItemsControl.Resources>

            </ItemsControl.Resources>

            <ItemsControl.ItemsPanel>
                <!-- specify the panel that is the container for the items -->
                <ItemsPanelTemplate>
                    <UniformGrid Rows="10" Columns="10" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <!-- specify the template used to render each item -->
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type sys:String[]}">
                    <TextBox Text="{Binding Path=., UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Button Content="Read cell 0/0" Click="Button_Click_1"/>
        <TextBlock x:Name="Cell00"/>
    </StackPanel>
</Grid>

我只想将 ObservableCollection myMatrixData 中的元素反映在一个名为 myMatrixUniformGrid 样式 ItemsControl 中。更改第一个单元格中的文本并按下按钮表明这不起作用。

我错过了什么?

【问题讨论】:

  • 您的财产变更通知在哪里?
  • 绑定在哪里?
  • 我怀疑属性更改通知是在 ObservableCollection 中处理的?绑定在这里:“
    不,您必须实现 INotifyPropertyChanged 或使用众多 MVVM 框架之一...
  • 我开始将收藏与我脑海中的财产分开......

标签: wpf binding textbox observablecollection uniformgrid


【解决方案1】:

ObservableCollection&lt;string&gt; 不会更新对string 的更改,因为string 本身没有实现INotifypropertyChanged

尝试为您的收藏创建一个简单的模型

例子:

private ObservableCollection<Matrix> _myMatrix = new ObservableCollection<Matrix>();

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;

    for (int i = 0; i < 100; i++)
    {
        MyMatrix.Add(new Matrix { Value = "Test" + i });
    }
}

public ObservableCollection<Matrix> MyMatrix
{
    get { return _myMatrix; }
    set { _myMatrix = value; }
}

.......


public class Matrix : INotifyPropertyChanged
{
    private string _value;
    public string Value
    {
        get { return _value; }
        set { _value = value; NotifyPropertyChanged("Value"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

Xaml:

<Window x:Class="WpfApplication9.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication9"
        Title="MainWindow" Height="350" Width="525" Name="UI">
    <StackPanel>
        <ItemsControl x:Name="myMatrix" ItemsSource="{Binding MyMatrix}" >
            <ItemsControl.ItemsPanel>
                <!-- specify the panel that is the container for the items -->
                <ItemsPanelTemplate>
                    <UniformGrid Rows="10" Columns="10" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <!-- specify the template used to render each item -->
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type local:Matrix}">
                    <TextBox Text="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Button Content="Read cell 0/0" Click="Button_Click_1" />
        <TextBlock x:Name="Cell00" />
    </StackPanel>

</Window>

【讨论】:

  • 太好了,谢谢!不知何故,我认为 ObservableCollection 是一个“包罗万象”的课程,因为从源头转移工作正常。
【解决方案2】:

我发现这对于使用 NotifyPropertyChanged 和命令进行绑定非常有用

wpf-mvvm-inotifypropertychanged

Implementing the MVVM Pattern

WPF/MVVM Quick Start Tutorial --- Super Handy This One

【讨论】:

  • 谢谢,其中两个我还没有读过。我当然想应用 M-V-VM 模式并且现在有几十个教程,为了清楚起见,我在这里省略了 M-V-VM。最后一步是从数据模型中的字符串中剥离 ObservableCollection 并使用 INotify...
猜你喜欢
相关资源
最近更新 更多
热门标签