【问题标题】:Two way data binding in a GridViewGridView 中的两种方式数据绑定
【发布时间】:2009-02-02 21:04:10
【问题描述】:

我们有一个应用,它使用简单的单向绑定与 GridView 来显示一些数据。好吧,现在我们需要允许用户更改其中的一些数据,所以我一直在尝试让两种方式的数据绑定在 GridView 中工作。到目前为止,一切都正确显示,但在 GridView 中编辑单元格似乎什么也没做。我在搞砸什么?像这样的双向数据绑定甚至可能吗?我是否应该开始将所有内容转换为使用不同的控件,比如 DataGrid?

我编写了一个小型测试应用程序来显示我的问题。如果你尝试一下,你会发现属性设置器在初始化后永远不会被调用。

Xaml:

    Title="Window1" Height="300" Width="300">
    <Grid>
        <ListView Name="TestList">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Strings">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Text="{Binding Path=String, Mode=TwoWay}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Bools">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Path=Bool, Mode=TwoWay}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

下面是对应的代码:

using System.Collections.Generic;
using System.Windows;

namespace GridViewTextbox
{
    public partial class Window1 : Window
    {
        private List<TestRow> _rows = new List<TestRow>();

        public Window1()
        {
            InitializeComponent();

            _rows.Add(new TestRow("a", false));
            _rows.Add(new TestRow("b", true));
            _rows.Add(new TestRow("c", false));

            TestList.ItemsSource = _rows;
            TestList.DataContext = _rows;
        }
    }

    public class TestRow : System.Windows.DependencyObject
    {
        public TestRow(string s, bool b)
        {
            String = s;
            Bool = b;
        }

        public string String
        {
            get { return (string)GetValue(StringProperty); }
            set { SetValue(StringProperty, value); }
        }

        // Using a DependencyProperty as the backing store for String.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StringProperty =
            DependencyProperty.Register("String", typeof(string), typeof(TestRow), new UIPropertyMetadata(""));


        public bool Bool
        {
            get { return (bool)GetValue(BoolProperty); }
            set { SetValue(BoolProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Bool.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BoolProperty =
            DependencyProperty.Register("Bool", typeof(bool), typeof(TestRow), new UIPropertyMetadata(false));
    }
}

【问题讨论】:

  • 建议:ObservableCollection 而不是 List

标签: wpf xaml gridview data-binding two-way-binding


【解决方案1】:

当您使用依赖属性时,Setter 不会被绑定调用,而是直接更改值(使用 SetValue 或类似的东西)。

尝试添加一个PropertyChangedCallback,并在其中设置一个断点以查看该值是否从GridView更改。

public static readonly DependencyProperty BoolProperty =
    DependencyProperty.Register("Bool", typeof(bool), typeof(TestRow), new UIPropertyMetadata(false, OnBoolChanged));
private static void OnBoolChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    //this method will be called everytime Bool changes value
}

【讨论】:

  • AAGH。我过去也使用过它,但今天它逃脱了我。谢谢!
【解决方案2】:

如果它们是依赖属性,则不会从 WPF 调用属性设置器。这些被用作 CLR 便利,并被不知道 DependencyProperty 的代码调用。

WPF 代码可以:

yourControl.SetValue(TestRow.StringProperty, someValue);

不是:

yourControl.String = someValue;

您需要挂钩 DepedencyPropertyChanged 事件才能听到更改。

【讨论】:

    猜你喜欢
    • 2016-02-27
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多