简体   繁体   English

如何在设置其数据上下文时使用用户控件依赖项属性?

[英]How to use a user control dependency property when setting its data context?

I've made a user control which contains a command, to be called in response to a certain event. 我创建了一个包含命令的用户控件,以响应某个事件而调用。 This command is a dependency property. 此命令是依赖项属性。 I want to use it in the main window like this: 我想在主窗口中使用它,如下所示:

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

The "myCommand" is the dependency property I created for this user control. “myCommand”是我为此用户控件创建的依赖项属性。 And I bind it to a command of the view model of the main window ("someCommand"). 然后我将它绑定到主窗口的视图模型的命令(“someCommand”)。

The problem is that I am setting the datacontext of my usercontrol (I have a view model for it), and it seems to reset the "Command" to null… Here is the code-behind of my view model: 问题是我正在设置我的usercontrol的datacontext(我有一个视图模型),它似乎将“Command”重置为null ...这是我的视图模型的代码隐藏:

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);
    }
}

The code of my user control could be the Following: 我的用户控件的代码可能是以下内容:

<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>

(I know that this element seems a bit silly (or useless), but I have simplified it to test what didn't worked and also in order to ask a rather simple question). (我知道这个元素看起来有点愚蠢(或无用),但我已经简化它来测试什么没有用,也是为了问一个相当简单的问题)。

I have discovered that, if I comment the "this.DataContext = new myViewModel();" 我发现,如果我评论“this.DataContext = new myViewModel();” line, the binding to the command works perfectly. 对命令的绑定工作完美。 And when I uncomment this line and put a breakpoint in the "TextBlock_MouseUp", the "Command" property is equal to null... 当我取消注释这一行并在“TextBlock_MouseUp”中放置一个断点时,“Command”属性等于null ...

Would there be a way to resolve this problem? 有没有办法解决这个问题? I have some complicated code in my view model (so I'm quite forced to keep this line "this.DataContext = new myViewModel();"), and I am not sure I could find another solution than having a "Command" dependency property in my user control… 我的视图模型中有一些复杂的代码(所以我非常强迫这行“this.DataContext = new myViewModel();”),我不确定我能找到另一个解决方案,而不是“命令”依赖我的用户控件中的属性...

To be sure I give a maximum of informations, I have the following code in the view model of my main window: 为了确保我提供最多的信息,我在主窗口的视图模型中有以下代码:


public ICommand someCommand { get; set; }

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

(The RelayCommand class is a standard RelayCommand class, with a "Predicate" CanExecute and an "Action Execute). (RelayCommand类是标准的RelayCommand类,带有“Predicate”CanExecute和“Action Execute”。

I hope this question is not a duplicate… I have found several similar question, but they did not seem to answer mine... 我希望这个问题不重复......我发现了几个类似的问题,但他们似乎没有回答我的问题......

I'm really sorry for this question which was in fact a bit silly. 我真的很抱歉这个问题实际上有点傻。 I hadn't understand very well what happens during a binding. 我不太了解绑定期间会发生什么。 I thought that this code line in the MainWindow… 我认为MainWindow中的这段代码行......

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

…would have made an attempt to bind the UserControl's "Command" property to the "someCommand" of the datacontext of the MainWindow . ...会尝试将UserControl的“Command”属性绑定到MainWindow的datacontext的“someCommand”。 In fact, as @elgonzo pointed out, the binding looks up in the UserControl's datacontext for the "someCommand" property (and not in the MainWindow's datacontext!!). 事实上,正如@elgonzo指出的那样,绑定在UserControl的 datacontext中查找“someCommand”属性(而不是在MainWindow的datacontext !!中)。 Therefore, setting the UserControl's datacontext with this line… 因此,使用此行设置UserControl的datacontext ...

this.DataContext = new myViewModel();

...was preventing the binding to be correctly done (since it looks for the "someCommand" property of the UserControl's datacontext, which is now "myViewModel", which does not contain "someCommand"...). ...阻止绑定正确完成(因为它查找UserControl的datacontext的“someCommand”属性,现在是“myViewModel”,它不包含“someCommand”...)。

To fix this, I had to change the binding like this: 要解决这个问题,我必须像这样更改绑定:

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

I've found this solution here: https://stackoverflow.com/a/1127964/11609068 . 我在这里找到了这个解决方案: https//stackoverflow.com/a/1127964/11609068

Maybe it is not the best way to do it (the "Path= DataContext. someCommand" make me think this, it doesn't seem very elegant), but it works. 也许它不是最好的方法(“Path = DataContext。someCommand ”让我觉得这个,它看起来并不优雅),但它确实有效。 Another way to do it is to name the MainWindow (x:Name="someName"), so that the binding is a bit simpler: 另一种方法是命名MainWindow(x:Name =“someName”),以便绑定更简单:

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

Again, sorry and many thanks to @elgonzo. 再次,抱歉,非常感谢@elgonzo。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在同一用户控件中使用依赖属性? - How to use a dependency property in the same user control? 当绑定数据更改时,用户控件上的依赖项属性不会更新属性 - Dependency Property on a user control not updating the property when bound data changes 设置控件的属性时,可以在控件名称中使用字符串吗? - Can you use a string in the name of the control when setting its property? 如何在用户控件上使用具有依赖属性的属性触发器? - How to use property triggers with dependency properties on a user control? 如何通过设置容器控件依赖项属性来修改内部控件属性? - How to modify inner control property by setting container control dependency property? 如何将自定义控件的依赖项属性绑定到其视图模型属性 - How to bind a dependency property for a custom control to its view models property WPF用户控件依赖项属性绑定到ViewModel属性时不起作用 - WPF User Control Dependency Property not working when bound to a ViewModel property 在自定义控件中设置控件的依赖项属性 - Setting a dependency property of a control in the custom control 何时在自定义控件中使用属性而不是依赖属性? - When to use a Property over a Dependency Property in a custom control? 在 XAML 中为用户控件设置一个属性 - Setting a property in XAML for a User Control
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM