Xaml双向绑定文本框到可观察的集合 [英] Xaml two way binding of textbox to observable collection

查看:154
本文介绍了Xaml双向绑定文本框到可观察的集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的WP8应用程序中,我有一个类,它有一个 ObservableCollection< ObservableCollection< int> 属性称为Matrix。



我想使用项目控件显示这些矩阵。

 < ItemsControl ItemsSource ={Binding FirstMatrix.Matrix }> 
< ItemsControl.ItemTemplate>
< DataTemplate>
< ItemsControl ItemsSource ={Binding}>
< ItemsControl.ItemsPanel>
< ItemsPanelTemplate>
< StackPanel Orientation =Horizo​​ntal>< / StackPanel>
< / ItemsPanelTemplate>
< /ItemsControl.ItemsPanel>
< ItemsControl.ItemTemplate>
< DataTemplate>
< TextBox Text ={Binding}/>
< / DataTemplate>
< /ItemsControl.ItemTemplate>
< / ItemsControl>
< / DataTemplate>
< /ItemsControl.ItemTemplate>
< / ItemsControl>

该代码在显示方面可以工作(它是使用默认值的零填充的)。但是我也想允许在TextBox中进行更改,这将在Matrix属性中反映出来 - 现在TextBox不能被更改,因为它们的值绑定到Matrix单元格的一个方法。我尝试设置< TextBox Text ={Binding Mode = TwoWay}/> 或sth相似,但似乎不起作用。
任何想法应该如何绑定数据?



编辑:
我已经实现了INotifyPropertyChanged。
这是我的课程的一部分:

  public partial class CalcMatrix:INotifyPropertyChanged 
{
public ObservableCollection< ObservableCollection< int>> Matrix
{
get {return _matrix; }
set
{
_matrix = value;
OnPropertyChanged(Matrix);
}
}
private ObservableCollection< ObservableCollection< int>> _矩阵;

private void OnPropertyChanged(string argName)
{
var handler = PropertyChanged;
if(handler!= null)
处理程序(this,new PropertyChangedEventArgs(argName));
}
public event PropertyChangedEventHandler PropertyChanged;
}

我认为TexBoxes不改变的原因是因为绑定是一个 - 文本一直是Matrix中的内容。我相信我应该以某种方式改变XAML绑定到TwoWay或某些东西,但不知道如何。任何想法?

解决方案

双向模式绑定需要路径(为什么?看到这个SO答案),所以你不能像 {Binding Mode = TwoWay} 那样做,它必须像 {Binding SomePath,Mode = TwoWay} 。因此,在这种情况下,您必须将矩阵项包装为一些类而不是纯int,并将该int作为该类的属性的值。

  //您的Matrix属性类型变成:
...
public ObservableCollection< ObservableCollection< MatrixElement>> Matrix
...

// MatrixElement类是这样的:
public class MatrixElement:INotifyPropertyChanged
{
private int _value;
public int Value
{
get {return _value; }
set {
_value = value;
OnPropertyChanged(Value);
}
}

....
}

//那么你可以用双向模式绑定TextBox
...
< ItemsControl.ItemTemplate>
< DataTemplate>
< TextBox Text ={Binding Value,Mode = TwoWay}/>
< / DataTemplate>
< /ItemsControl.ItemTemplate>
...


In my WP8 app I have a class, which has a ObservableCollection<ObservableCollection<int>> property called Matrix.

I want to display these matrices using items control.

 <ItemsControl ItemsSource="{Binding FirstMatrix.Matrix}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <ItemsControl ItemsSource="{Binding}">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal"></StackPanel>
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <TextBox Text="{Binding}" />
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

The code works as far as displaying is concerned (it's filled with zeros which is a default value). But I also want to allow changes in TextBoxes which would be reflected in Matrix property - now the TextBoxes can't be changed, because their value is bound one way to Matrix cells I guess. I tried setting <TextBox Text="{Binding Mode=TwoWay}" />or sth similar but it doesn't seem to work. Any ideas how should the data be bound ?

EDIT: I have implemented the INotifyPropertyChanged. Here is a part of my class:

public partial class CalcMatrix : INotifyPropertyChanged
    {
        public ObservableCollection<ObservableCollection<int>> Matrix 
        { 
            get { return _matrix; }
            set
            {
                _matrix = value;
                OnPropertyChanged("Matrix");
            } 
        }
        private ObservableCollection<ObservableCollection<int>> _matrix;

        private void OnPropertyChanged(string argName)
        {
            var handler = PropertyChanged;
            if(handler != null)
                handler(this, new PropertyChangedEventArgs(argName));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }

I think the reason the TexBoxes don't change is because the binding is one-way - the Text is always what is inside the Matrix. I believe that i should somehow change the XAML binding to TwoWay or something but don't know how. Any ideas ?

解决方案

Two way mode binding require path (why? see this SO answer), so you can't do it just like {Binding Mode=TwoWay}, it has to be something like {Binding SomePath, Mode=TwoWay}. Therefore, in this case you have to wrap matrix item to be some class instead of plain int and put that int as property's value of that class.

//your Matrix property type become:
...
public ObservableCollection<ObservableCollection<MatrixElement>> Matrix
...

//MatrixElement class is something like:
public class MatrixElement : INotifyPropertyChanged
{
    private int _value;
    public int Value
    {
        get { return _value; }
        set { 
                _value = value; 
                OnPropertyChanged("Value"); 
            }
    }

    ....
}

//then you can bind TextBox in two way mode
...
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <TextBox Text="{Binding Value, Mode=TwoWay}" />
    </DataTemplate>
</ItemsControl.ItemTemplate>
...

这篇关于Xaml双向绑定文本框到可观察的集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆