【问题标题】:WPF: How to use dependecy property value in another dependecy property?WPF:如何在另一个依赖属性中使用依赖属性值?
【发布时间】:2011-07-22 04:19:06
【问题描述】:

好的,这有点复杂。我创建了一个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();
    }
}

问题是我不知道如何从MonthViewControl 访问Date 依赖属性以便在MonthWeekControl 中使用它。正如您在MonthWeekControlWeekNumber 依赖属性的定义中看到的那样,它需要日期才能计算周数。

请帮忙。谢谢!

【问题讨论】:

    标签: wpf wpf-controls binding dependency-properties


    【解决方案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

    【讨论】:

      【解决方案2】:

      您可以在实例构造函数中设置绑定,而不是在 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 */
          });
      }
      

      【讨论】:

      • Sergii,我喜欢你的绑定方法——它使过程自动化。我创建了一个静态方法Utilities.GetWeekInYear(DateTime date),以便从日期中获取周数。我应该从转换器调用这个方法吗?
      • 看来我将无法使用绑定和转换器。每周的日期需要不同,否则所有MonthWeekControl 控件都会为WeekNumber 属性获取相同的值:)
      猜你喜欢
      • 2020-10-19
      • 2014-05-23
      • 2011-12-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      • 1970-01-01
      相关资源
      最近更新 更多