WPF用户控件: can I bind properties from an internal and an external datacontext?

标签 wpf xaml mvvm data-binding calendar

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

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

其中 DayItem 可以表示约会或待办事项等内容。

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

包含此日历的 View (用户控件)在概念上如下所示:

<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 设置为某个 View 模型类,该类具有属性 DaysWithItems(CalenderDay 的列表) 实例)和属性 DisplayMonth

理想情况下,此日历控件的使用者只需提供所提到的两个输入。此外,从 myView 的角度来看(双关语是巧合),DaysWithItems 应该是一个包含 28、29、30 或 31 个元素的列表,具体取决于月份。这意味着列表应该以某种方式填充到 42 个项目。我认为这应该是日历控件的责任,而不是 myView 的 View 模型。

请注意,我也没有提供日期名称。这也应该是日历控件的责任。不应明确提供这一点。

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

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

最佳答案

绑定(bind)到 DataContext 之外的其他内容的最简单方法是使用 ElementName

您可以执行以下操作:

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


    }

用户控件.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,并能够绑定(bind)到 UC 内的属性。

关于WPF用户控件: can I bind properties from an internal and an external datacontext?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27938921/

相关文章:

wpf - 通过XAML将Window.Content设置为页面吗?

c# - Xamarin Forms PCL with Caliburn,只有创建 View 层次结构的原始线程才能触及其 View

wpf - 组合框鼠标悬停

c# - WPF 上的 MSCharts

c# - 在按钮 WPF 中添加带有 fontawesome 的文本

c# - 使用 <Style TargetType= 时无法转换错误

c# - 按名称查找 WPF 控件

c# - WPF中的绑定(bind)问题——属性和字段的区别

wpf - 在 MVVM 架构中应在何处以及如何管理选定的项目?

c# - MVVM 上 ViewModel 设计中的继承