WPF:如何在另一个依赖项属性中使用依赖项属性值?

时间:2011-03-24 14:04:29

标签: wpf wpf-controls binding dependency-properties

好吧,这有点复杂。我创建了一个MonthViewControl用户控件:

的Xaml:

<UserControl x:Class="MonthView.Controls.MonthViewControl"
             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:controls="clr-namespace:MonthView.Controls" 
             DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <!-- The following line is important! -->
    <TextBlock Text="{Binding Path=Date, Converter={...}}" />
    <ItemsControl>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="6" Columns="1" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <controls:MonthWeekControl />
        <controls:MonthWeekControl />
        <controls:MonthWeekControl />
        <controls:MonthWeekControl />
        <controls:MonthWeekControl />
        <controls:MonthWeekControl />
    </ItemsControl>
</UserControl>

代码隐藏:

public partial class MonthViewControl : UserControl
{
    public static readonly DependencyProperty DateProperty =
        DependencyProperty.Register("Date", typeof(DateTime), 
        typeof(MonthViewControl), 
        new UIPropertyMetadata(DateTime.Today));

    public DateTime Date
    {
        get { return (DateTime)GetValue(DateProperty); }
        set { SetValue(DateProperty, value); }
    }

    public MonthViewControl()
    {
        InitializeComponent();
    }
}

接下来,我创建了MonthWeekControl用户控件:

的Xaml:

<UserControl x:Class="MonthView.Controls.MonthWeekControl"
             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:controls="clr-namespace:MonthView.Controls"
             DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Border Grid.Column="0">
            <!-- The following line is important! -->
            <TextBlock Text="{Binding Path=WeekNumber}" />
        </Border>
        <ItemsControl Grid.Column="1">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Rows="1" Columns="7" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <controls:MonthDayControl />
            <controls:MonthDayControl />
            <controls:MonthDayControl />
            <controls:MonthDayControl />
            <controls:MonthDayControl />
            <controls:MonthDayControl />
            <controls:MonthDayControl />
        </ItemsControl>
    </Grid>
</UserControl>

代码背后:

public partial class MonthWeekControl : UserControl
{
    public static readonly DependencyProperty WeekNumberProperty =
        DependencyProperty.Register("WeekNumber", typeof(int), 
        typeof(MonthWeekControl), 
        new UIPropertyMetadata(Utilities.GetWeekInYear(dateFromMonthViewControl)));
    // Utilities.GetWeekInYear(DateTime date) gets the week number 
    // based on the provided date

    public int WeekNumber
    {
        get { return (int)GetValue(WeekNumberProperty); }
        set { SetValue(WeekNumberProperty, value); }
    }

    public MonthWeekControl()
    {
        InitializeComponent();
    }
}

问题是,我不知道如何从Date获取MonthViewControl依赖项属性,以便在MonthWeekControl中使用它。正如您在WeekNumber的{​​{1}}依赖项属性的定义中所看到的,它需要日期才能计算周数。

请帮忙。谢谢!

2 个答案:

答案 0 :(得分:1)

您拥有的这行代码是静态的。这意味着它只会被执行一次 - 并且它不能引用任何不是静态的东西。

public static readonly DependencyProperty WeekNumberProperty =
   DependencyProperty.Register("WeekNumber", typeof(int),         
     typeof(MonthWeekControl),         
     new UIPropertyMetadata(Utilities.GetWeekInYear(dateFromMonthViewControl)));

抛弃您在这里的UIPropertyMetadata - 这是为所有类的实例设置默认初始值。在这种情况下,这是不合适的。

相反,让MonthViewControl遍历每个MonthWeekControl,并根据需要在它们上设置WeekNumber属性。只要MonthViewControl的Date属性发生更改,就这样做。所以现在的挑战是要知道Date属性发生了什么变化......将用于注册此属性的UIPropertyMetadata更改为采用回调方法的属性。只要属性发生更改,就会调用此回调 - 然后在设置varios WeekNumber值的位置调用此回调。有关详细信息,请参阅此处:http://msdn.microsoft.com/en-us/library/ms557330.aspx

答案 1 :(得分:0)

您可以在实例构造函数中设置绑定,而不是在MonthWeekControl中设置WeekNumber依赖项属性的默认值:

public MonthWeekControl()
{
    InitializeComponent();
    SetBinding(WeekNumberProperty, new Binding("Date")
    {
        RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor,
            typeof (MonthViewControl)),
        Converter = /* an instance of Date-to-WeekNumber converter */
    });
}