【问题标题】:dataBinding a UserControl to data in DataGrid [duplicate]将用户控件绑定到 DataGrid 中的数据 [重复]
【发布时间】:2019-10-08 01:15:38
【问题描述】:

我在使用Dependency Property 绑定数据时遇到了一个小问题;

我有一个包含textBox 的用户控件。我创建了一个DataGrid,并在其中为其中一列添加了usercontrol。然后我使用 dataContext 进行了绑定。

当我第一次运行应用程序时,用户控件填充了数据(在我的情况下,数据绑定到特定字段“名称”),但是当我修改值时,新值没有写入,它仍然保留旧值价值。

TT.xaml.cs

namespace WPF_Prj.View
{
    public partial class TT : UserControl
    {
        public float MyText
        {
            get { 
                return (float)GetValue(MyTextProperty); 
            }
            set { 
                SetValue(MyTextProperty, value ); 
            }
        }

    public static readonly DependencyProperty MyTextProperty =
        DependencyProperty.Register("MyText", typeof(float), typeof(TT), new FrameworkPropertyMetadata(null) { BindsTwoWayByDefault = true });

    public TT()
    {
        InitializeComponent();
    }
}

}

TT.xaml

<UserControl x:Class="WPF_Prj.View.TT"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <TextBox Height="20" Width="100" 
                Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, 
                Path=MyText, 
                UpdateSourceTrigger=PropertyChanged}">
    </TextBox>
</Grid>

mainWindow.xaml

<Window x:Class="WPF_Prj.View.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:col="clr-namespace:System.Collections;assembly=mscorlib"
    xmlns:local="clr-namespace:WPF_Prj.View"
    Title="[Portfolio] MainWindow" Height="500" Width="800">

<StackPanel Orientation="Vertical">

    <DataGrid x:Name="datagrid" AutoGenerateColumns="False" CanUserAddRows="False"
            Width="Auto" Margin="5,5,0,5" HorizontalAlignment="Left" CellEditEnding="datagrid_CellEndEditing">
        <DataGrid.Columns>
            <DataGridTextColumn Header=""                                                                                            IsReadOnly="True"  Width="1"/>
            <DataGridTextColumn Header="Name"           Binding="{Binding Name, Mode=TwoWay, NotifyOnTargetUpdated=True}"            IsReadOnly="True"  Width="Auto"/>
            <DataGridTextColumn Header="Owned Qty"      Binding="{Binding OwnedQty, Mode=TwoWay, NotifyOnTargetUpdated=True}"        IsReadOnly="True"  Width="Auto"/>
            <DataGridTemplateColumn Header="Ordered/Eligible">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:TT x:Name="test" MyText="{Binding OwnedQty, Mode=TwoWay}"></local:TT>
                    </DataTemplate> 
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
    </StackPanel>

在 mainWindow.xaml.cs 中,我从实现 ObservableCollectionViewModel 类获取数据,而模型是实现 INotifyPropertyChanged 的类

所以在下图中:绿色框是从我的数据库加载到网格的内容,红色是我的用户控件,它保存和编辑,起初它包含加载的值,但是当我将其更改为其他值时值,绿色中的值仍然不变。

【问题讨论】:

标签: wpf data-binding


【解决方案1】:

这为我解决了这个问题。你不需要Mode=TwoWay;在依赖属性定义中已经是默认的了。您确实需要UpdateSourceTrigger=PropertyChanged,无论它是否在 DP 定义中。

<DataTemplate>
    <local:TT 
        x:Name="test" 
        MyText="{Binding OwnedQty, UpdateSourceTrigger=PropertyChanged}"
        ></local:TT>
</DataTemplate>

我希望能够通过在依赖属性定义中初始化 DefaultUpdateSourceTrigger 来做同样的事情,但这不会产生相同的效果。我不知道为什么会这样。

请注意,我还将默认值更改为0Fnull 会抛出异常。

public static readonly DependencyProperty MyTextProperty =
    DependencyProperty.Register("MyText", typeof(float), typeof(TT), 
        new FrameworkPropertyMetadata(0F) {
            BindsTwoWayByDefault = true
            //  Nope. 
            //, DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
        });

这是我的视图模型属性。我在OnPropertyChanged() 上设置了一个断点,以检测绑定何时更新了属性。

private float _ownedQty = 0F;
public float OwnedQty
{
    get { return _ownedQty; }
    set
    {
        if (value != _ownedQty)
        {
            _ownedQty = value;
            OnPropertyChanged();
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-06-09
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 2013-08-29
    相关资源
    最近更新 更多