【问题标题】:WPF Databinding not working in both directions when DataGrid bound to Observable Collection of Properties with Sub properties当 DataGrid 绑定到具有子属性的可观察属性集合时,WPF 数据绑定无法双向工作
【发布时间】:2014-01-22 02:22:43
【问题描述】:

请原谅这个冗长的标题,我在描述简洁时遇到了麻烦。如果我能想出一个,我可能会在谷歌上找到正确的答案!

我将我的 DataGrid 绑定到一个 ObservableCollection 属性,这些属性本身具有属性。我的网格填充得很好,但是当我编辑网格时,更改并没有回到我的模型中。 我有一个 ObservableCollection

通常情况下,您只有一些 MarriedCoupleRow 的属性,但实际上我有一些稍微复杂的东西。每个 MarriedCoupleRow 都有一些属性(男性、女性),这些属性又会暴露属性(身高、体重、信息)。这是可以编辑的信息。同样,我可以很好地填充网格,但是当您编辑单元格并关闭(或离开)标签时,不会点击 Information 的 setter 属性。

我将不胜感激任何指针或参考,包括如何更好地表达我的标题!

这是简单的代码:

 public class XMLDemoViewModel : ViewModelBase
{

    public XMLDemoViewModel()
    {

        _rows = new ObservableCollection<MarriedCoupleRow>();
        // create some data....
        for (uint i = 0; i < 2;i++)
        {
            MarriedCoupleRow row = new MarriedCoupleRow();
            row.Male = new HumanData();
            row.Male.Height = (70 + i*5).ToString();
            row.Male.Weight = 150+(i*30+1);
            row.Male.Information = row.Male.Height + " " + row.Male.Weight;

            row.Female = new HumanData();
            row.Female.Height = (60 +i*3).ToString();
            row.Female.Weight = 120+(i*10+5);
            row.Female.Information = row.Female.Height + " " + row.Female.Weight;
            _rows.Add(row);
        }
    }


    #region Fields

    private ObservableCollection<MarriedCoupleRow> _rows = null; 


    #endregion Fields

    #region Properties

    public ObservableCollection<MarriedCoupleRow> Rows
    {
        get
        {
            return _rows;

        }

    }
    #endregion Properties
    #region Commands


    #endregion Commands

    #region Private Methods


    #endregion Private Methods
}

public class MarriedCoupleRow : ViewModelBase
{
    private HumanData _Male = null;

    public HumanData Male
    {
        get { return _Male; }
        set
        {
            if (value != _Male)
            {
                _Male = value;
                OnPropertyChanged("Male");
            }
        }
    }
    public HumanData Female { get; set; }

}

public class HumanData : INotifyPropertyChanged
{
    public string Height { get; set; }
    public uint Weight { get; set; }

    private string _friendlyName;
    public string Information
    {
        get
        {
            return _friendlyName;

        }
        set
        {
            if (_friendlyName != value)
            {
                _friendlyName = value;
                OnPropertyChanged("Information");
            }
        }
    }


}

这是 XAML:

<Window x:Class="XMLDemo.Views.XMLDemoView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="XMLDemoView"  Height="600" Width="1152">

    <DockPanel>
        <StackPanel Orientation="Horizontal" Height="120" DockPanel.Dock="Bottom">
            <StackPanel Orientation="Horizontal">
                <GroupBox Width="249" BorderThickness="2" Height="90">
                    <GroupBox.Header>
                        <TextBlock FontSize="12" FontWeight="Bold">Control</TextBlock>
                    </GroupBox.Header>
                    <Grid Height="64" Width="223">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="0.5*" />
                            <ColumnDefinition Width="0.5*" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="0.5*"/>
                            <RowDefinition Height="0.5*"/>
                        </Grid.RowDefinitions>

                    </Grid>

                </GroupBox>
            </StackPanel>
        </StackPanel>
    <DataGrid ItemsSource="{Binding Path=Rows,  UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False">

        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.HeaderTemplate >
                    <DataTemplate>
                        <Grid ShowGridLines="True">
                            <Grid.RowDefinitions>
                                <RowDefinition />

                            </Grid.RowDefinitions>
                            <TextBlock Text="Male"  />

                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.HeaderTemplate>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <TextBox Text="{Binding Male.Height}" IsEnabled="False"  Grid.Row="0"></TextBox>
                            <TextBox Text="{Binding Male.Weight}" IsEnabled="False" Grid.Row="1"></TextBox>
                            <TextBox Text="{Binding Male.Information, Mode=TwoWay}"   Grid.Row="2"></TextBox>
                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.HeaderTemplate >
                    <DataTemplate>
                        <Grid ShowGridLines="True">
                            <Grid.RowDefinitions>
                                <RowDefinition />

                            </Grid.RowDefinitions>
                            <TextBlock Text="Female"  />

                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.HeaderTemplate>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Grid >
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <TextBox Text="{Binding Female.Height}" IsEnabled="False"  Grid.Row="0"></TextBox>
                            <TextBox Text="{Binding Female.Weight}" IsEnabled="False" Grid.Row="1"></TextBox>
                            <TextBox Text="{Binding Female.Information}" Grid.Row="2"></TextBox>
                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

        </DataGrid.Columns>
    </DataGrid>
    </DockPanel>

【问题讨论】:

    标签: wpf data-binding wpfdatagrid observablecollection


    【解决方案1】:

    您的 TextBox.Text 绑定需要在 propertychanged 上设置为 updatesource。

    <TextBox Text="{Binding Male.Information, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"   Grid.Row="2"></TextBox>
    

    默认设置的 LostFocus 肯定有一些愚蠢的地方。我使用您的代码对此进行了测试。

    【讨论】:

    • 谢谢李欧!我在 行上有 UpdateSourceTrigger 并认为这就足够了。显然不是!标记为答案。
    【解决方案2】:

    我喜欢你的帖子。正如我从编码中看到的那样,您正在将复杂属性绑定与 DataGrid 结合使用。复杂的属性更改也不会反映在 DataGrid 中。

    但是,您可以在样本级别达到此要求。我会尝试制作样品并通知您。

    问候, 里亚杰·艾哈迈德一世

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-05
      • 2021-11-22
      • 1970-01-01
      • 2015-03-07
      • 2016-11-08
      • 1970-01-01
      相关资源
      最近更新 更多