将UserControl绑定到DataGrid中的数据

时间:2019-05-21 15:34:16

标签: wpf data-binding

我遇到了一个小问题,使用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中,我从实现ViewModel的{​​{1}}类中获取数据,而Model是实现ObservableCollection的类

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

enter image description here

1 个答案:

答案 0 :(得分:2)

这为我解决了。您不需要Mode=TwoWay;默认情况下,依赖项属性定义中已经存在该内容。无论是否在DP定义中,都需要UpdateSourceTrigger=PropertyChanged

<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
        });

这是我的viewmodel属性。我在OnPropertyChanged()上放置一个断点,以检测何时通过绑定更新属性。

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