Silverlight Data Grid twoway Связывание данных в коде - PullRequest
1 голос
/ 06 марта 2012

У меня есть DataGrid с двухсторонним связыванием, и я не уверен, почему это не работает, любая помощь будет оценена.

Я хотел динамически привязаться к DataGrid, используя объект привязки twoway.

Я использовал столбцы в XAML.Если я просто устанавливаю свойство ItemSource напрямую - оно работает, но тогда две привязки не работают - если я изменяю свой источник в коде, Grid не отражает это изменение.

Я создал простой примерчтобы проиллюстрировать мою настройку

Вот код XAML

<UserControl x:Class="SilverlightApplication1.MainPage"
    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"
    mc:Ignorable="d"
    d:DesignHeight="356" d:DesignWidth="590" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">

    <Grid x:Name="LayoutRoot" Background="White"> 
        <sdk:DataGrid AutoGenerateColumns="False" Height="136" HorizontalAlignment="Left" Margin="71,116,0,0" Name="MyGrid" VerticalAlignment="Top" Width="453" >
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Binding="{Binding Path=Label, Mode=TwoWay}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="Auto" Header="Selected" />
                <sdk:DataGridTextColumn Binding="{Binding Path=YValue, Mode=TwoWay}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Header="Name" Width="*" />
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
    </Grid>
</UserControl>

Вот код

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent(); 
            ObservableCollection<Value> values = new ObservableCollection<Value>(); 
            values.Add(new Value() { Label = "Sony", YValue = 50 });
            values.Add(new Value() { Label = "Dell", YValue = 35 });
            values.Add(new Value() { Label = "HP", YValue = 27 });
            values.Add(new Value() { Label = "HCL", YValue = 17 });
            values.Add(new Value() { Label = "Toshiba", YValue = 16 });

            PagedCollectionView p = new PagedCollectionView(values); 

            Binding b = new Binding("ValuesBinding");
            b.Mode = BindingMode.TwoWay;
            b.Source = values;
            MyGrid.SetBinding(DataGrid.ItemsSourceProperty, b);  
        }
    }

    public class Value : INotifyPropertyChanged
    {
        public String Label
        {
            get
            { return _label; }
            set
            {
                _label = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("Label"));
            }
        }
         public Double YValue
        {
            get
            {return _yValue;}
            set
            {
                _yValue = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("YValue"));
            }
        }
        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
        Double _yValue;
        String _label;
    } 

}

1 Ответ

1 голос
/ 06 марта 2012

Здесь я вижу несколько проблем.

Первая строка, которую вы используете для создания привязки:

Binding b = new Binding("ValuesBinding");

Это не будет делать то, что вы хотите.Строка ValuesBinding используется как путь к свойству, а у коллекции ObservableCollection, к которой вы привязываете DataGrid, нет свойства с именем ValuesBinding.Действительно, если вы посмотрите в окно VS Output, вы должны увидеть сообщение, такое как

System.Windows.Data Error: BindingExpression path error: 'ValuesBinding' property not found on 'System.Collections.ObjectModel.ObservableCollection`1 ...

Однако, если вы удалите "ValuesBinding" из вышеприведенного, чтобы оставить вас с

Binding b = new Binding();

тогда вы получите ошибку о двухсторонних привязках, нуждающихся в Path.Однако здесь вам не нужно двустороннее связывание.Вы можете просто удалить строку b.Mode = BindingMode.TwoWay; и ошибка исчезнет.

Двусторонние привязки используются, чтобы позволить слою вида устанавливать свойства в слое модели вида.Path указывает, где найти свойство view-model для установки.Тем не менее, поскольку вы привязываете напрямую к коллекции, свойство не задействовано и, следовательно, ничего не может установить на уровне представления.

В вашем случае эта привязка не обязательно должна быть двусторонней.Изменения в самой коллекции (например, добавление или удаление элементов) все еще могут быть сделаны, даже если используется односторонняя привязка для ItemsSource.Двусторонние привязки, которые есть в свойствах Label и YValue вашего класса Value, также будут работать так, как вы ожидаете.Установка односторонней привязки для ItemSrid ItemsSource не делает всю сетку доступной только для чтения.

Наконец, я не уверен, почему вы создаете привязку в коде для привязки к коллекции.уже доступно в коде позади.Вы можете добиться того же, просто написав

MyGrid.ItemsSource = values;
...