UserControl的RelativeSource-Binding

时间:2015-03-16 11:29:12

标签: c# wpf user-controls

我已经在我的应用程序中创建了一个UserControl来显示超链接。

UserControl的标记如下:

<UserControl x:Class="MVVMExample.View.UserControls.ActionLink"
             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"
             DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <TextBlock Margin="5">
                <Hyperlink Command="{Binding LinkCommand}" CommandParameter="{Binding LinkCommandParameter}">
                    <TextBlock Text="{Binding LinkText, UpdateSourceTrigger=PropertyChanged}"/>
                </Hyperlink>
        </TextBlock>
    </Grid>
</UserControl>

DataContext的{​​{1}}位于CodeBehind中,如下所示:

UserControl

一切都很好。

现在,如果我想在命令绑定中使用此public partial class ActionLink : UserControl, INotifyPropertyChanged { public static readonly DependencyProperty LinkTextProperty = DependencyProperty.Register( "LinkText", typeof (string), typeof (ActionLink), new PropertyMetadata(LinkTextChanged)); public static readonly DependencyProperty LinkCommandParameterProperty = DependencyProperty.Register( "LinkCommandParameter", typeof (object), typeof (ActionLink), new PropertyMetadata(LinkCommandParameterChanged)); public static readonly DependencyProperty LinkCommandProperty = DependencyProperty.Register( "LinkCommand", typeof (ICommand), typeof (ActionLink), new PropertyMetadata(LinkCommandChanged)); public ActionLink() { InitializeComponent(); } public object LinkCommandParameter { get { return GetValue(LinkCommandParameterProperty); } set { SetValue(LinkCommandParameterProperty, value); } } public string LinkText { get { return (string) GetValue(LinkTextProperty); } set { SetValue(LinkTextProperty, value); OnPropertyChanged(); } } public ICommand LinkCommand { get { return (ICommand) GetValue(LinkCommandProperty); } set { SetValue(LinkCommandProperty, value); } } public event PropertyChangedEventHandler PropertyChanged; private static void LinkTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((ActionLink) d).LinkText = (string) e.NewValue; } private static void LinkCommandParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((ActionLink) d).LinkCommandParameter = e.NewValue; } private static void LinkCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((ActionLink) d).LinkCommand = (ICommand) e.NewValue; } protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } ,我必须执行以下操作:

UserControl

如果我使用的是<userControls:ActionLink LinkText="View customers" LinkCommand="{Binding DataContext.ViewCustomersCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"/> ,我就不必提供Button。我是否有机会在自定义创建的RelativeSource s的绑定属性上提供RelativeSource

1 个答案:

答案 0 :(得分:2)

写作时

<userControls:ActionLink LinkCommand="{Binding ViewCustomersCommand}"/>

WPF尝试在UserControl的DataContext中建立与ViewCustomersCommand属性的数据绑定,该属性通常从控件的父级继承,并保存对某个视图模型对象的引用。这在此处不起作用,因为您已将DataContext显式设置为UserControl实例。

只要在UserControl中具有可绑定属性(即依赖项属性),就不应该设置其DataContext。如果这样做,您将始终必须明确指定绑定源对象,因为不再继承DataContext。

所以删除

DataContext="{Binding RelativeSource={RelativeSource Self}}"

从UserControl的XAML进行设置,并在其所有内部绑定中设置RelativeSource:

<Hyperlink
    Command="{Binding LinkCommand,
              RelativeSource={RelativeSource AncestorType=UserControl}}"
    CommandParameter="{Binding LinkCommandParameter,
                       RelativeSource={RelativeSource AncestorType=UserControl}}">
    <TextBlock
        Text="{Binding LinkText,
               RelativeSource={RelativeSource AncestorType=UserControl}
               UpdateSourceTrigger=PropertyChanged}"/>
</Hyperlink>