WPF用户控件:是否可以从内部和外部数据上下文绑定属性? [英] WPF User control: can I bind properties from an internal and an external datacontext?

查看:71
本文介绍了WPF用户控件:是否可以从内部和外部数据上下文绑定属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在WPF/XAML中构建自己的日历控件,既作为练习,又用于业余爱好项目.该日历将是一个网格,其中每个单元格显然代表所选月份中的一天.每个单元格应该能够显示项目列表.日历的输入应该是一个月的标识和几天的列表.那些日子"将是自定义类型,例如

I am trying to build my own calendar control in WPF/XAML, both as an exercise and to be used in a hobby project. This calender will be a grid where each cell obviously represents a day in the chosen month. Each cell should be able to display a list of items. The inputs for the calendar should be an identification of a month and a list of days. Those "days" will be of a custom type, something like

public class CalendarDay
{
    public int DayNumber {get; set;}
    public List<DayItem> Items {get; set;}
}

其中 DayItem 可以表示约会或待办事项.

where a DayItem could represent something like an appointment or a todo.

我正在将其实现为用户控件.此日历的XAML是一个 ControlTemplate ,其中包含1x7的日期名称(绑定到集合7字符串的数据)和一个 UniformGrid UniformGrid .>的天数为6x7(数据绑定到 CalendarDay 的集合).

I'm implementing this as a user control. The XAML for this calendar is a ControlTemplate that contains a UniformGrid of 1x7 for the day names (data bound to a collection 7 strings) and a UniformGrid of 6x7 for the days (data bound to a collection of CalendarDay).

在这个日历上包含的视图(用户控件)在概念上看起来像这样:

A view (user control) that contains this calendar conceptually looks like this:

<UserControl name="myView" ... xmlns:cal="clr-namespace:the calendar namespace">

    <Grid>
        <cal:Calendar Days="{Binding DaysWithItems}" CurrentMonth="{Binding DisplayMonth}" />
    </Grid>

</UserControl>

当我应用MVVM时, myView 将具有一个DataContext,该DataContext设置为具有属性 DaysWithItems ( CalenderDay的列表)的某些视图模型类实例)和属性 DisplayMonth .

As I'm applying MVVM, myView will have a DataContext that is set to some view model class that has a property DaysWithItems (a list of CalenderDay instances) and a property DisplayMonth.

理想地,此日历控件的使用者只需要提供上述两个输入即可.此外,从 myView 的角度来看(是巧合的), DaysWithItems 应该是28、29、30或31个元素的列表,具体取决于月份.这意味着该列表应以某种方式填充到42个项目中.我认为这应该是日历控件的责任,而不是 myView 的视图模型.

Ideally, the consumer of this calendar control should only have to provide the two inputs as mentioned. Moreover, DaysWithItems should, from myView's point of view (pun is coincidental), be a list of 28, 29, 30 or 31 elements, depending on the month. This means that the list should somehow be padded to 42 items. I think this should be the responsibility of the calendar control, not myView's view model.

请注意,我也没有提供日期名称.这也应该是日历控件的责任.不应明确提供此信息.

Note that I'm also not provding the day names. This too should be the responsibility of the calendar control. This shouldn't be provided explicitly.

这是我的问题.如果在日历的控制模板中,我想绑定到日期名称的字符串集合和 CalendarDay 的42个元素集合,则数据上下文应该是 Calendar 类本身(由于我之前解释的职责).另一方面,在 myView 中,我将日历绑定到 myView DaysWithItems (包含28个值的(逻辑)集合)中..31个元素),因此日历的数据上下文应该是 myView 的视图模型.

Here's my problem. If, in the calendar's control template, I want to bind to the string collection for the day names and the 42 element collection of CalendarDay, the datacontext should be the Calendar class itself (because of the responsibilities I explained earlier). On the other hand, in myView, I'm binding the calendar to myView's DaysWithItems (the (logical) collection that contains 28..31 elements), so there the calendar's datacontext should be myView's view model.

我可以使用某种内部数据上下文(=控件模板的内部"),也可以使用某种外部数据上下文(=日历控件的使用者提供的数据上下文)吗?

Can I use some sort of internal datacontext (= "internal" to the control template) and also some sort of external datacontext (= a datacontext as provided by the consumer of the calendar control)?

推荐答案

绑定到DataContext以外的其他东西的最简单方法是使用ElementName

The easiest way to bind to something other than your DataContext is by using ElementName

您可以执行以下操作:

UserControl.xaml.cs的示例:

Example for UserControl.xaml.cs:

public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }



        public int MyProperty
        {
            get { return (int)GetValue(MyPropertyProperty); }
            set { SetValue(MyPropertyProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.Register("MyProperty", typeof(int), typeof(UserControl1), new PropertyMetadata(0));


    }

UserControl.Xaml

UserControl.Xaml

<UserControl x:Class="GridSplitterTest.UserControl1"
             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:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" x:Name="MyControl"
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Button Content="{Binding ElementName=MyControl, Path=MyProperty}"></Button>
    </Grid>
</UserControl>

通过使用ElementName并指向UserControl,您将绕过DataContext并能够绑定到UC内部的属性.

By using ElementName and pointing to the UserControl you are bypassing the DataContext and able to bind to properties inside your UC.

这篇关于WPF用户控件:是否可以从内部和外部数据上下文绑定属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆