UserControl 的 RelativeSource 绑定
RelativeSource-Binding for UserControl
我创建了一个 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>
此 UserControl
的 DataContext
在 CodeBehind 中,如下所示:
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
。有没有机会我也不必提供 RelativeSource
关于自定义创建的 UserControl
的绑定属性?
写的时候
<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}}"/>
</Hyperlink>
我创建了一个 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>
此 UserControl
的 DataContext
在 CodeBehind 中,如下所示:
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
。有没有机会我也不必提供 RelativeSource
关于自定义创建的 UserControl
的绑定属性?
写的时候
<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}}"/>
</Hyperlink>