Двухстороннее связывание данных в GridView - PullRequest
2 голосов
/ 03 февраля 2009

У нас есть приложение, которое использует простую одностороннюю привязку с 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));
    }
}

Ответы [ 2 ]

6 голосов
/ 03 февраля 2009

Когда вы используете свойства зависимости, сеттеры не будут вызываться привязками, вместо этого они изменяют значение напрямую (используя 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
}
1 голос
/ 03 февраля 2009

Установщики свойств НЕ будут вызываться из WPF, если они являются свойствами зависимостей. Они используются для удобства CLR и вызываются кодом, который не знает о DependencyProperty.

Код WPF будет делать:

yourControl.SetValue(TestRow.StringProperty, someValue);

Не:

yourControl.String = someValue;

Вам нужно перехватить событие DepedencyPropertyChanged, чтобы услышать изменения.

...