将UserControl DependencyProperty绑定到其他UserControl DependencyProperty

时间:2012-05-31 19:20:02

标签: c# silverlight dependency-properties

我有两个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);
        }
    }

}

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

}

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

MKSelectPeriodForChatReportCW上的属性确实获取值(来自它们的绑定)但MKSelectMonthUC上的值没有。所以请帮我找一个解决方案。感谢。

1 个答案:

答案 0 :(得分:0)

我没有您的所有源代码,我无法重现您的问题,所以我所能做的就是根据您上面提到的代码风格提出一些建议。

  1. 正如HiTechMagic所说,GetChatReport中的ChatRoomId设置器中的MKSelectMonthUC方法调用不会像您预期的那样经常被调用。如果希望每次依赖项属性更改时都调用方法,请使用PropertyChangedCallbackThis page on MSDN有一个如何使用PropertyChangedCallback的示例。

    对于由依赖项属性支持的属性,getter应该只包含对GetValue的调用,而setter只应包含对SetValue的调用。

  2. 使用ElementName的绑定可能很难处理,因为如果出现问题它们是静默的(例如,找不到具有给定名称的元素)。假设您在视图模型中的某个位置具有CurrentYearChatRoomId属性的值,如果是,我建议将CurrentYearChatRoomId个依赖属性绑定到视图模型中的数据。

  3. 两个依赖项属性之间的绑定最好与表示层信息一起使用。例如,您可以使用两个依赖项属性之间的绑定来确保两个控件具有相同的宽度。这些控件的宽度是表示层数据,因为它不是您要呈现的数据,但它是 您呈现它的方式。您的CurrentYearChatRoomId属性是您要显示的数据,而不是您展示的数据,因此它们不是表示层数据。

  4. 我还建议不要给顶级元素Namex:Name,然后在绑定中使用该名称。不可否认,您展示的唯一XAML是ChildWindow,因此我不知道您的MKSelectMonthUC用户控件是否也是如此。尽管如此,为了将来的参考,以及其他读过这个答案的人,我会给出两个理由,说明这是一个坏主意。

    假设我们有以下UserControl

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

    如果我们然后尝试使用此控件并为其指定不同的x:Name,例如

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

    我们最终将控件的名称从myUc更改为abc123,这会破坏绑定。

    此外,如果我们尝试使用这些用户控件中的两个或多个,例如

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

    然后我们收到关于x:Name不唯一的错误,因为MyUserControl个元素都有x:Name myUc