我继续使用code of MSDN了解MVVC,我有一个问题。
在.xaml中,他们有一个显示在屏幕上的命令列表。
<Border
Grid.Column="0"
Style="{StaticResource MainBorderStyle}"
Width="170"
>
<HeaderedContentControl
Content="{Binding Path=Commands}"
ContentTemplate="{StaticResource CommandsTemplate}"
Header="Control Panel"
Style="{StaticResource MainHCCStyle}"
/>
</Border>
从这里,我知道DataContext已设置(此处未显示),它将显示命令集合。我不明白的是您可以在下面看到的CommandsTemplate:
<DataTemplate x:Key="CommandsTemplate">
<ItemsControl IsTabStop="False" ItemsSource="{Binding}" Margin="6,2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="2,6">pou
<Hyperlink Command="{Binding Path=Command}">
<TextBlock Text="{Binding Path=DisplayName}" />
</Hyperlink>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
如何创建绑定?这段代码如何告诉从集合中的对象检查属性Command和DisplayName?它来自ItemsSource吗?如果是,我不明白为什么它只在{Binding}。任何人都可以向我解释一下DataTemplate绑定如何在ContentTemplate中运行?
答案 0 :(得分:9)
正如您所说,DataContext设置为ViewModel类,因此您在XAML中提到的控件将能够访问该ViewModel的公共属性。
例如:
private ObservableCollection<Commander> commands = new ObservableCollection<Commander>();
public ObservableCollection<Commander> Commands {
get { return commands; }
set { commands = value; }
}
Commander类的结构。
public class Commander {
public ICommand Command { get; set; }
public string DisplayName { get; set; }
}
该VM具有名为Commands的属性,该属性可能是ObservableCollection。可以从XAML访问此属性。
你可以想象HeaderedContentControl是一个容器。 HeaderedContentControl的内容是DataTemplate“CommandsTemplate”,它具有ItemsControl并且它绑定到VM的Commands属性。
Content =“{Binding Path = Commands}”
然后,您可以再次将ItemControl与Commands绑定,但ItemControl位于绑定到Commands的内容中。因此,您无需再次指定路径。你可以使用
ItemsSource="{Binding}" instead of ItemsSource="{Binding Commands}".
ItemControl中有两个文本块,因此它们与Commander ObservableCollection的Commander类处于同一级别。这就是你可以直接访问Text =“{Binding Path = DisplayName}”的原因。
希望它有所帮助。
答案 1 :(得分:1)
与{Binding}绑定的ItemsSource直接绑定到ItemsControl的DataContext(它将查找链,直到找到一个设置的DataContext)。在这种情况下,它已在HeaderedContentControl中设置
ItemsControl中的每个项目都将其DataContext设置为列表中的元素。
<ItemsControl.ItemTemplate>
正在为列表中的每个项目设置模板,而不是为ItemsControl本身设置模板。因此{Binding Path=Command}
和{Binding Path=DisplayName}
会查看列表中元素的这些属性。
答案 2 :(得分:1)
示例:
<强> XAML 强>
<Window x:Class="WpfApplication2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
<Window.Resources>
<DataTemplate x:Key="CommandsTemplate">
<ItemsControl IsTabStop="False" ItemsSource="{Binding}" Margin="6,2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="2,6">pou
<Hyperlink Command="{Binding Path=Command}">
<TextBlock Text="{Binding Path=DisplayName}" />
</Hyperlink>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<Grid>
<Border Width="170">
<HeaderedContentControl
Content="{Binding Path=Commands}"
ContentTemplate="{StaticResource CommandsTemplate}"
Header="Control Panel"/>
</Border>
</Grid>
</Window>
<强> C#强>
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window {
public Window1() {
InitializeComponent();
Commands.Add(new Commander() { DisplayName = "DN1" });
Commands.Add(new Commander() { DisplayName = "DN2" });
Commands.Add(new Commander() { DisplayName = "DN3" });
this.DataContext = this;
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
}
private ObservableCollection<Commander> commands = new ObservableCollection<Commander>();
public ObservableCollection<Commander> Commands {
get { return commands; }
set { commands = value; }
}
}
public class Commander {
public ICommand Command { get; set; }
public string DisplayName { get; set; }
}