gpt4 book ai didi

c# - 设置数据上下文时如何使用用户控件依赖属性?

转载 作者:行者123 更新时间:2023-11-30 17:26:19 26 4
gpt4 key购买 nike

我制作了一个用户控件,其中包含一个命令,将被调用以响应特定事件。此命令是一个依赖属性。我想像这样在主窗口中使用它:

<local:myUserControl Command="{Binding someCommand}"/>

“myCommand”是我为此用户控件创建的依赖属性。我将它绑定(bind)到主窗口 View 模型的命令(“someCommand”)。

问题是我正在设置我的用户控件的数据上下文(我有一个 View 模型),它似乎将“命令”重置为空……这是我的 View 模型的代码隐藏:

public partial class myUserControl : UserControl, ICommandSource
{
public myUserControl()
{
this.DataContext = new myViewModel();

InitializeComponent();
}

public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(myUserControl), new PropertyMetadata(null));



public object CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(myUserControl), new PropertyMetadata(0));



public IInputElement CommandTarget
{
get { return (IInputElement)GetValue(CommandTargetProperty); }
set { SetValue(CommandTargetProperty, value); }
}
public static readonly DependencyProperty CommandTargetProperty =
DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(myUserControl), new PropertyMetadata(null));



private void TextBlock_MouseUp(object sender, MouseButtonEventArgs e)
{
Command.Execute(this.CommandParameter);
}
}

我的用户控件的代码可能如下:

<UserControl x:Class="myApp.myUserControl"
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"
xmlns:local="clr-namespace:myApp"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock MouseUp="TextBlock_MouseUp">
</TextBlock>
</Grid>
</UserControl>

(我知道这个元素看起来有点傻(或无用),但我已将其简化以测试无效的内容,同时也是为了提出一个相当简单的问题)。

我发现,如果我评论“this.DataContext = new myViewModel();”行,对命令的绑定(bind)工作得很好。当我取消注释此行并在“TextBlock_MouseUp”中放置一个断点时,“Command”属性等于 null...

有什么办法可以解决这个问题吗?我的 View 模型中有一些复杂的代码(所以我不得不保留这一行“this.DataContext = new myViewModel();”),而且我不确定我能找到除了“命令”依赖之外的另一种解决方案我的用户控件中的属性...

为了确保我提供最多的信息,我在主窗口的 View 模型中有以下代码:


public ICommand someCommand { get; set; }

//Constructor
public MainWindowViewModel()
{
this.someCommand = new RelayCommand((obj) => { return true; },
(obj) =>
{
//I put a breakpoint here
int dummy = 0;
});
}

(RelayCommand 类是一个标准的 RelayCommand 类,带有“Predicate”CanExecute 和“Action Execute”。

我希望这个问题不是重复的……我发现了几个类似的问题,但他们似乎没有回答我的……

最佳答案

对于这个实际上有点愚蠢的问题,我真的很抱歉。我不太了解绑定(bind)过程中会发生什么。我认为 MainWindow 中的这段代码行......

<local:myUserControl Command="{Binding someCommand}"/>

…会尝试将 UserControl 的“Command”属性绑定(bind)到 MainWindow 的数据上下文的“someCommand”。事实上,正如@elgonzo 指出的那样,绑定(bind)在UserControl 的 数据上下文中查找“someCommand”属性(而不是在MainWindow 的数据上下文中!!)。因此,用这一行设置 UserControl 的数据上下文……

this.DataContext = new myViewModel();

...阻止正确完成绑定(bind)(因为它查找 UserControl 的数据上下文的“someCommand”属性,现在是“myViewModel”,不包含“someCommand”...)。

要解决这个问题,我必须像这样更改绑定(bind):

<local:myUserControl Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, 
Path=DataContext.someCommand}"/>

我在这里找到了这个解决方案:https://stackoverflow.com/a/1127964/11609068 .

也许这不是最好的方法(“Path= DataContext. someCommand”让我这么想,它看起来不太优雅),但它确实有效。另一种方法是命名 MainWindow (x:Name="someName"),这样绑定(bind)就更简单了:

<local:myUserControl Command="{Binding ElementName=someName, Path=DataContext.someCommand}"/>

再次抱歉,非常感谢@elgonzo。

关于c# - 设置数据上下文时如何使用用户控件依赖属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56913566/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com