简体   繁体   English

将UserControl DependencyProperty绑定到其他UserControl DependencyProperty

[英]Binding UserControl DependencyProperty to other UserControl DependencyProperty

I have two UserControls: 我有两个UserControls:

public partial class MKSelectMonthUC : UserControl
{
    public static readonly DependencyProperty CurrentYearProperty = DependencyProperty.Register("CurrentYear", typeof(int), typeof(MKSelectMonthUC), new PropertyMetadata(0));
    public int CurrentYear
    {
        get { return (int)GetValue(CurrentYearProperty); }
        set
        {
            SetValue(CurrentYearProperty, value);
        }
    }

    public static readonly DependencyProperty ChatRoomIdProperty = DependencyProperty.Register("ChatRoomId", typeof(int), typeof(MKSelectMonthUC), new PropertyMetadata(0));
    public int ChatRoomId
    {
        get { return (int)GetValue(ChatRoomIdProperty); }
        set
        {
            SetValue(ChatRoomIdProperty, value);
            if(value > 0)
                GetChatReport(ChatRoomId);
        }
    }

} }

and

public partial class MKSelectPeriodForChatReportCW : ChildWindow
{
    public static readonly DependencyProperty ChatRoomIdProperty = DependencyProperty.Register("ChatRoomId", typeof(int), typeof(MKSelectPeriodForChatReportCW), new PropertyMetadata(0));
    public int ChatRoomId
    {
        get { return (int)GetValue(ChatRoomIdProperty); }
        set
        {
            SetValue(ChatRoomIdProperty, value);
        }
    }

    public static readonly DependencyProperty CurrentYearProperty = DependencyProperty.Register("CurrentYear", typeof(int), typeof(MKSelectPeriodForChatReportCW), new PropertyMetadata(0));
    public int CurrentYear
    {
        get { return (int)GetValue(CurrentYearProperty); }
        set
        {
            SetValue(CurrentYearProperty, value);
        }
    }

} }

in XAML of MKSelectPeriodForChatReportCW I want to bind it's DependencyProperties to MKSelectMonthUC DependencyProperties like that: 在MKSelectPeriodForChatReportCW的XAML中,我想将其DependencyProperties绑定到MKSelectMonthUC DependencyProperties上,如下所示:

<controls:ChildWindow x:Class="XX.mkControls.MKSelectPeriodForChatReportCW"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
       xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" 
       xmlns:mk="clr-namespace:XX.mkControls.MKSelectPeriodForChatReport"
       Name="mainControl"
       >
<Grid x:Name="LayoutRoot" Margin="2">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <mk:MKSelectMonthUC CurrentYear="{Binding CurrentYear, ElementName=mainControl}" ChatRoomId="{Binding ChatRoomId, ElementName=mainControl}" />


</Grid>

Properties on MKSelectPeriodForChatReportCW do get values (from their bindings) but values on MKSelectMonthUC don't. MKSelectPeriodForChatReportCW上的属性确实从其绑定中获取值,但MKSelectMonthUC上的属性却无法获取。 So please help me find a solution. 因此,请帮助我找到解决方案。 Thanks. 谢谢。

I don't have all your source code and I cannot reproduce your problem, so all I can do is to make some suggestions based on the style of code you've presented above. 我没有您所有的源代码,也无法重现您的问题,所以我所能做的就是根据您上面介绍的代码样式提出一些建议。

  1. As HiTechMagic says, the GetChatReport method call in the ChatRoomId setter in MKSelectMonthUC won't get called as often as you might expect. 作为HiTechMagic称, GetChatReport在方法调用ChatRoomId在二传手MKSelectMonthUC不会得到尽可能多你所期望的调用。 If you want a method to be called every time a dependency property changes, use a PropertyChangedCallback . 如果希望每次依赖项属性更改时都调用一个方法,请使用PropertyChangedCallback This page on MSDN has an example of how to use a PropertyChangedCallback. MSDN上的此页面提供了有关如何使用PropertyChangedCallback的示例。

    For a property backed by a dependency property, the getter should only contain a call to GetValue and the setter should only contain a call to SetValue . 对于由依赖项属性支持的属性,getter仅应包含对GetValue的调用,而setter应仅包含对SetValue的调用。

  2. Bindings using ElementName can be awkward to work with because they are silent if something goes wrong (eg no element with the given name was found). 使用ElementName进行绑定可能很麻烦,因为如果出现问题(例如,未找到具有给定名称的元素),它们将保持沉默。 Presumably you have values for your CurrentYear and ChatRoomId properties somewhere in your view-model, and if so, I'd recommend binding both CurrentYear and both ChatRoomId dependency properties to data in your view-model. 假定您在视图模型中的某处具有CurrentYearChatRoomId属性的值,如果是这样,我建议将CurrentYearChatRoomId依赖项属性都绑定到视图模型中的数据。

  3. Bindings between two dependency properties are best used with presentation-layer information. 两个依赖项属性之间的绑定最好与表示层信息一起使用。 For example, you might use a binding between two dependency properties to ensure two controls are the same width. 例如,您可以在两个依赖项属性之间使用绑定,以确保两个控件的宽度相同。 The width of these controls is presentation-layer data since it isn't what data you're presenting, but it's how you're presenting it. 这些控件的宽度为表现层的数据,因为它是不是你提出什么样的数据,但它是你如何呈现它。 Your CurrentYear and ChatRoomId properties are the data you're showing, not how you're showing it, so they're not presentation-layer data. CurrentYearChatRoomId属性是显示的数据,而不是显示方式,因此它们不是表示层数据。

I would also recommend against giving top-level elements a Name or an x:Name and then using that name in a binding. 我也建议不要给顶级元素一个Name或一个x:Name ,然后在绑定中使用该名称。 Admittedly, the only XAML you've shown is your ChildWindow , so I don't know whether your MKSelectMonthUC user-control does the same. 诚然,您显示的唯一XAML是ChildWindow ,所以我不知道您的MKSelectMonthUC用户控件是否执行相同的操作。 Nonetheless, for future reference, and for anyone else reading this answer, I'll give two reasons why this is a bad idea. 尽管如此,为了将来参考,以及对于其他阅读此答案的人,我将给出两个理由说明为什么这不是一个好主意。

Suppose we have the following UserControl : 假设我们有以下UserControl

<UserControl x:Class="XYZ.MyUserControl"
             ....
             x:Name="myUc">
    <TextBlock Text="{Binding Path=MyProperty, ElementName=myUc}" />
</UserControl>

If we then attempt to use this control and give it a different x:Name , such as 如果我们随后尝试使用此控件并给它一个不同的x:Name ,例如

<xyz:MyUserControl x:Name="abc123" />

we end up changing the name of the control from myUc to abc123 , and this breaks the binding. 我们最终将控件的名称从myUcabc123 ,这破坏了绑定。

Furthermore, if we attempt to use two or more of these user controls, for example 此外,例如,如果我们尝试使用两个或多个这些用户控件,

<StackPanel>
    <xyz:MyUserControl />
    <xyz:MyUserControl />
</StackPanel>

then we get an error about x:Name s not being unique, as both MyUserControl elements have an x:Name of myUc . 那么我们会收到关于x:Name不是唯一的错误,因为两个MyUserControl元素的x:Name都是myUc

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM