WPF嵌套数据绑定到控件 - 为什么它不起作用

时间:2016-01-20 09:54:25

标签: c# .net wpf data-binding

我搜索了google和stackoverflow很多,但没有任何运气,我找到了问题的答案。我找到了问题的解决方案。例如:

Data Binding to Nested Properties?

但我已经知道了解决方案。我想知道为什么wpf不支持控件上的嵌套/点缀数据绑定。

解决方案是将父控件的DataContext设置为父数据对象,在我的情况下,我的控制器/窗口datacontext上的ViewModel属性。所以我可以设置我的网格的DataContext,如果我将TextBox绑定更改为仅使用Name属性,我的代码将起作用。

另一个解决方案是明确地在我的TextBox上设置UpdateSourceTrigger并将我的嵌套数据绑定保存在TextBox控件上,如下所示。

但为什么呢?为什么WPF不像我在下面那样支持嵌套绑定而不设置UpdateSourceTrigger?我想知道:)。

我有这个文本框控件:

<Window>
    <Grid>
        <StackPanel>
            <Label Content="Name" FontWeight="Bold"/>
            <TextBox x:Name="NameTextBox" Text="{Binding Path=CreateEditAssetViewModel.Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Width="475" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalContentAlignment="Stretch" Margin="0, 5" />
        </StackPanel>
    </Grid>
</Window>

我的窗口datacontext绑定如下:

var createEditWindow = new CreateEditWindow();
var createEditController = new CreateEditWindowController();
createEditWindow.DataContext = createEditController;
createEditWindow.Show();

我的控制器看起来像这样:

public class CreateEditWindowController : ViewModelBase, ICreateEditWindowController
{
    private ICreateEditWindowViewModel _createEditWindowViewModel;
    public ICreateEditWindowViewModel CreateEditAssetViewModel
    {
        get { return _createEditWindowViewModel; }
        set
        {
            if (_createEditWindowViewModel == value) return;
            _createEditWindowViewModel = value;
            OnPropertyChanged(nameof(CreateEditAssetViewModel));
        }
    }
}

我的ViewModel与文本框控件绑定的Name属性如下所示:

public class CreateEditWindowViewModel : ViewModelBase, ICreateEditWindowViewModel
{

    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value) return;
            _name = value;
            OnPropertyChanged(nameof(Name));
        }
    }
}

我的ViewModelBase:

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

3 个答案:

答案 0 :(得分:1)

此处https://msdn.microsoft.com/en-us/library/ms752347%28v=vs.100%29.aspx

查看提供视觉反馈部分,它是一个触发器绑定属性,但它们使用了点缀属性

集合视图部分相同 - &gt;如何创建视图

他们在Application对象上使用了点缀属性。

在调试GUI时查看输出视图,如果WPF在数据上下文中找不到属性,它将抛出一个日志!

答案 1 :(得分:0)

WPF确实支持点状属性,但是您总是需要指定控制数据上下文。

答案 2 :(得分:0)

我认为wpf确实支持嵌套/点缀数据绑定。我在你提到的链接中发布了一个答案。 其中

<TextBox Text="{Binding Path=MyModel.MyCounter.CurrentNumber}"/>

绑定工作正常。不是这里,但我做了很多嵌套属性需要绑定到某些控件属性的示例。事实上,WPF必须支持这种类型的绑定,否则将单独的DataContext提供给单独的控件将是非常困难的工作。

一些例子:

1

<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type iDP:DataRecordCellArea}},Path=Record.DataItem.IsParentRow}" Value="true">
 <Setter Property="IsEnabled" Value="False"/>

2

<CheckBox HorizontalAlignment="Center"
                          VerticalAlignment="Center"
                          Cursor="Arrow" 
                          IsChecked="{Binding Path=DataItem.IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type view:DeleteSubLocationsView}},Path=DataContext.ImportWizardViewModel.ContextObject.IsRQSReviewFieldChecked}">

example how nested binding work