【发布时间】:2014-10-29 14:09:57
【问题描述】:
我一直找不到一个干净、简单的示例来说明如何正确在 MVVM 框架内使用具有 DependencyProperty 的 WPF 实现用户控件。每当我为用户控件分配DataContext 时,下面的代码都会失败。
我正在尝试:
- 从调用 ItemsControl 设置
DependencyProperty,然后 - 使
DependencyProperty的值可用于被调用用户控件的 ViewModel。
我还有很多东西要学,真诚感谢任何帮助。
这是最顶层用户控件中的ItemsControl,它使用DependencyProperty TextInControl 调用InkStringView 用户控件(来自另一个问题的示例)。
<ItemsControl ItemsSource="{Binding Strings}" x:Name="self" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="v:InkStringView">
<Setter Property="FontSize" Value="25"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</DataTemplate.Resources>
<v:InkStringView TextInControl="{Binding text, ElementName=self}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这是带有DependencyProperty 的InkStringView 用户控件。
XAML:
<UserControl x:Class="Nova5.UI.Views.Ink.InkStringView"
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"
x:Name="mainInkStringView"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding TextInControl, ElementName=mainInkStringView}" />
<TextBlock Grid.Row="1" Text="I am row 1" />
</Grid>
</UserControl>
代码隐藏文件:
namespace Nova5.UI.Views.Ink
{
public partial class InkStringView : UserControl
{
public InkStringView()
{
InitializeComponent();
this.DataContext = new InkStringViewModel(); <--THIS PREVENTS CORRECT BINDING, WHAT
} --ELSE TO DO?????
public String TextInControl
{
get { return (String)GetValue(TextInControlProperty); }
set { SetValue(TextInControlProperty, value); }
}
public static readonly DependencyProperty TextInControlProperty =
DependencyProperty.Register("TextInControl", typeof(String), typeof(InkStringView));
}
}
【问题讨论】:
-
ItemsControl(或任何派生类)的 ItemTemplate 中控件的 DataContext 由 WPF 自动分配给源集合中的相应项。在您的情况下,这将是
String集合中的一个元素。如果Strings是具有text属性的对象的集合,您只需将DataTemplate 中的绑定写为TextInControl="{Binding text}"并且不显式设置 任何其他DataContext。我建议阅读这个主题。 -
@Clemens 嗨。从调用 ItemsControl 中删除 ElementName= ... 仍然会显示“我是第 1 行”,并且第 0 行上的文本块应该是空白行。 ???想法?
-
字符串是 ObservableCollection
吗? -
@Lee O 是的。 Strings 是 ViewModel 中的 ObservableCollection,用于初始调用 ItemsControl。顺便说一句,如果我用一个简单的 TextBlock 替换用户控件,则所有内容都会显示并使用上述绑定正确运行。
标签: wpf mvvm data-binding user-controls dependency-properties