我有UserControl
LinkLabel
之前有一张图片。
XAML看起来像:
<UserControl>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Source={x:Static helper:ImageHelper.JumpLabelImage}}" Width="16" Height="16" VerticalAlignment="Center"/>
<TextBlock >
<Hyperlink Command="{Binding JumpCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
CommandParameter="{Binding CommandParameter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<TextBlock Text="{Binding LabelText, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" VerticalAlignment="Center" />
</Hyperlink>
</TextBlock>
</StackPanel>
</UserControl>
此UserControl
的DataContext设置为CodeBehind-File。
Code-Behind-File看起来像:
public partial class JumpLabel : UserControl
{
public static readonly DependencyProperty LabelTextProperty = DependencyProperty.Register("LabelText", typeof(string), typeof(JumpLabel));
public static readonly DependencyProperty JumpCommandProperty = DependencyProperty.Register("JumpCommand", typeof(ICommand), typeof(JumpLabel));
public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(JumpLabel));
public string LabelText
{
get { return (string)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
public ICommand JumpCommand
{
get { return (ICommand)GetValue(JumpCommandProperty); }
set { SetValue(JumpCommandProperty, value); }
}
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public JumpLabel()
{
InitializeComponent();
}
}
现在,如果用户点击LinkLabel
因此我使用以下代码在MainWindow的视图中分配命令:
<view:JumpLabel LabelText="Extensions" JumpCommand="{Binding JumpLabelCommand, UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding ElementName=control}"/>
在我的MainWindow的ViewModel中,我有:
private ICommand _jumpLabelCommand;
public ICommand JumpLabelCommand
{
get { return _jumpLabelCommand; }
set
{
_jumpLabelCommand = value;
OnPropertyChanged();
}
}
和
public MainWindowViewModel()
{
_mainWindowModel = new MainWindowModel();
JumpLabelCommand = new RelayCommand(DummyExecute);
}
private void DummyExecute(object parameter)
{
}
在DummyExecute中,我有一个永远不会到达的断点。我不知道为什么我的命令不起作用。我做错了什么?
更新
我创建了一个新的小项目,重点关注UserControl
中Command-Property的绑定问题。
MainWindowView是:
<Window x:Class="UCWithDP.View.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:UCWithDP.ViewModel"
xmlns:view="clr-namespace:UCWithDP.View"
Title="MainWindowView" Height="300" Width="600">
<Window.DataContext>
<viewModel:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="{Binding SomeText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<view:JumpLabel Grid.Row="1" JumpLabelText="My Jump Label" JumpCommand="{Binding DoJumpCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Grid.Row="2" Content="Some Button" Command="{Binding DoJumpCommand}"/>
</Grid>
</Window>
MainWindowViewModel是:
internal class MainWindowViewModel : ViewModelBase
{
private string _someText;
private ICommand doJumpCommand;
public MainWindowViewModel()
{
SomeText = "Hello from ViewModel";
DoJumpCommand = new RelayCommand(DoJumpExecute);
}
public string SomeText
{
get { return _someText; }
set
{
_someText = value;
OnPropertyChanged();
}
}
public ICommand DoJumpCommand
{
get { return doJumpCommand; }
set
{
doJumpCommand = value;
OnPropertyChanged();
}
}
private void DoJumpExecute(object parameter)
{
}
}
我的UserControl
是:
<UserControl x:Class="UCWithDP.View.JumpLabel"
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" Height="20"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
x:Name="uc">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="X" FontWeight="Bold" VerticalAlignment="Center" Margin="2"/>
<TextBlock Grid.Column="1" Margin="2">
<Hyperlink Command="{Binding ElementName=uc, Path=JumpCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TextBlock Text="{Binding JumpLabelText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center"/>
</Hyperlink>
</TextBlock>
</Grid>
</UserControl>
UserControl
的代码隐藏是
public partial class JumpLabel : UserControl
{
public static readonly DependencyProperty JumpLabelTextProperty = DependencyProperty.Register(
"JumpLabelText", typeof (string), typeof (JumpLabel), new PropertyMetadata(default(string)));
public static readonly DependencyProperty JumpCommandProperty = DependencyProperty.Register(
"JumpCommand", typeof (ICommand), typeof (JumpLabel), new PropertyMetadata(default(ICommand)));
public JumpLabel()
{
InitializeComponent();
}
public ICommand JumpCommand
{
get { return (ICommand) GetValue(JumpCommandProperty); }
set { SetValue(JumpCommandProperty, value); }
}
public string JumpLabelText
{
get { return (string) GetValue(JumpLabelTextProperty); }
set { SetValue(JumpLabelTextProperty, value); }
}
}
在MainWindowView中,UserControl
和Button
的命令属性绑定到同一ICommand
。如果我在DoJumpExecute中单击Button
我的断点。如果我点击HyperLink
未达到断点。
我仍然不理解......
解决方案
现在我在MainWindowView中使用以下代码
<view:JumpLabel Grid.Row="1" JumpLabelText="My Jump Label"
JumpCommand="{Binding DataContext.DoJumpCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"/>
现在可行。
答案 0 :(得分:1)
根据您提供的代码判断,您可能遇到任何问题...假设您确实拥有正确定义的所有属性,这些是最可能的错误原因:
首先,当从UserControl
XAML页面到其属性的数据绑定时,您应该习惯使用RelativeSource Binding
,尽管它的详细程度。请注意,您应该执行而不是将UserControl.DataContext
设置为其代码:
<Hyperlink Command="{Binding JumpCommand, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding CommandParameter,
RelativeSource={RelativeSource AncestorType={x:Type YourPrefix:YourUserControl}},
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TextBlock Text="{Binding LabelText, RelativeSource={RelativeSource AncestorType={
x:Type YourPrefix:YourUserControl}, UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}" VerticalAlignment="Center" />
</Hyperlink>
接下来,你有这行代码:
<view:JumpLabel LabelText="Extensions" JumpCommand="{Binding JumpLabelCommand,
UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding ElementName=
control}" />
如果满足以下任何条件,这当然不起作用:
ICommand
名为JumpLabelCommand
的属性,或后面的代码。control
的UI控件。DataContext
的UI控件的control
没有合适的值可用作CommandParameter
属性...也许这个Binding
应该是:{ {1}}?如果以上条件均不属实且您仍然遇到问题,请编辑您的问题并提供所有相关代码,其中应包含所有内容是相关的,例如。 CommandParameter="{Binding Propertyname, ElementName=control}"
元素的详细信息,集control
等
答案 1 :(得分:1)
这是一个更普遍的答案:如果你创建一个带有依赖属性的usercontrol,那么你的绑定应该总是包含某种&#34;相对绑定&#34; - 我总是使用elementname绑定。所以你的usercontrol绑定应该是这样的。
<UserControl x:Name="uc">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Source={x:Static helper:ImageHelper.JumpLabelImage}}" Width="16" Height="16" VerticalAlignment="Center"/>
<TextBlock >
<Hyperlink Command="{Binding ElementName=uc, Path=JumpCommand, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
CommandParameter="{Binding ElementName=uc, Path=CommandParameter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<TextBlock Text="{Binding ElementName=uc, Path=LabelText, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" VerticalAlignment="Center" />
</Hyperlink>
</TextBlock>
</StackPanel>
</UserControl>
如果您将usercontrol的datacontext设置为self,那么您将断开继承的datacontext,这不是您想要的。所以你必须在你的用户控件中删除所有类型的datacontext设置为self。
updatesource触发器用于处理源的更新,这就是为什么你的updatesource触发器在你的usercontrol中没有任何意义。例如,文本块无法将Text属性更新为源 - 它可以使用文本框:)
答案 2 :(得分:-1)
你的JumpLabel Control的构造函数应该是
public JumpLabel()
{
InitializeComponent();
this.DataContext=new MainWindowViewModel();
}