【问题标题】:Binding UserControl DependencyProperty to other UserControl DependencyProperty将 UserControl DependencyProperty 绑定到其他 UserControl DependencyProperty
【发布时间】:2012-06-06 02:00:30
【问题描述】:

我有两个用户控件:

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 上的值没有。所以请帮我找到解决方案。谢谢。

【问题讨论】:

  • 您是否期望GetChatReport(ChatRoomId) 被相关控件的更改触发?绑定不使用 Setter 和 Getter,仅使用 SetValueGetValue。它们只是为了您的方便。改为向该依赖项属性提供更改处理程序。

标签: c# silverlight dependency-properties


【解决方案1】:

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

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

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

  2. 使用 ElementName 的绑定可能很难使用,因为如果出现问题(例如,找不到具有给定名称的元素),它们会保持沉默。大概您的视图模型中某处的CurrentYearChatRoomId 属性具有值,如果是这样,我建议将CurrentYearChatRoomId 依赖属性都绑定到视图模型中的数据。

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

我还建议不要为顶级元素提供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:Names 不是唯一的错误,因为两个MyUserControl 元素都有x:NamemyUc

【讨论】:

    猜你喜欢
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 2012-03-02
    • 2013-01-20
    • 1970-01-01
    • 2014-06-22
    • 2016-05-13
    相关资源
    最近更新 更多