C# WPF数据模板和绑定
我继续我对MVVC的理解,我有一个问题 在.xaml中,它们有一个显示在屏幕上的命令列表C# WPF数据模板和绑定,c#,wpf,data-binding,.net-3.5,templates,C#,Wpf,Data Binding,.net 3.5,Templates,我继续我对MVVC的理解,我有一个问题 在.xaml中,它们有一个显示在屏幕上的命令列表 <Border Grid.Column="0" Style="{StaticResource MainBorderStyle}" Width="170" > <HeaderedContentControl Content="{Binding Path=Commands}" ContentTemplate="{Stat
<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>
浦
绑定是如何创建的?这段代码告诉我们如何从集合中的对象检查property命令和DisplayName?是从物品来源来的吗?如果是,我不明白为什么它只在{Binding}上。任何人都可以向我解释DataTemplate绑定如何从ContentTemplate开始工作?到{binding}的ItemsSource绑定直接绑定到ItemsControl的DataContext(它将查找链,直到找到一个设置的DataContext)。在这种情况下,它已在HeaderedContentControl中设置 ItemsControl中的每个项都将其DataContext设置为列表中的一个元素
正在为列表中的每个项目设置模板,而不是为ItemsControl本身设置模板。因此,{Binding Path=Command}
和{Binding Path=DisplayName}
将查看列表中元素上的那些属性。正如您所说,DataContext被设置为ViewModel类,以便您在XAML中提到的控件能够访问该ViewModel的公共属性
例如:
private ObservableCollection<Commander> commands = new ObservableCollection<Commander>();
public ObservableCollection<Commander> Commands {
get { return commands; }
set { commands = value; }
}
该VM具有名为Commands的属性,该属性可能是ObservableCollection。可以从XAML访问此属性
您可以想象HeaderedContentControl是一个容器。HeaderedContentControl的内容是一个DataTemplate“CommandsTemplate”,它有一个ItemsControl,并绑定到VM的Commands属性
Content=“{Binding Path=Commands}”
然后,您可以再次使用命令绑定ItemControl,但ItemControl位于绑定到命令的内容中。因此,无需再次指定路径。你可以用
ItemsSource="{Binding}" instead of ItemsSource="{Binding Commands}".
两个文本块位于ItemControl内部,因此它们与Commander命令类ObservableCollection处于同一级别。这就是为什么您可以直接访问Text=“{Binding Path=DisplayName}”
希望能有帮助 示例:
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#
//
///Window1.xaml的交互逻辑
///
公共部分类Window1:Window{
公共窗口1(){
初始化组件();
Commands.Add(newcommander(){DisplayName=“DN1”});
Commands.Add(newcommander(){DisplayName=“DN2”});
Commands.Add(newcommander(){DisplayName=“DN3”});
this.DataContext=this;
}
已加载私有无效窗口(对象发送器、路由目标){
}
私有ObservableCollection命令=新ObservableCollection();
公共可观察收集命令{
获取{return commands;}
设置{commands=value;}
}
}
公营班长{
公共ICommand命令{get;set;}
公共字符串DisplayName{get;set;}
}
如果它直接绑定到DataContext,它应该绑定到列表的上下文,而不是列表的元素?ItemsControl是这样,但是ItemsControl中的每个项都有一个列表的元素作为其DataContext。好的,那么使用{Binding}会在这个集合中搜索DataContext吗?我不明白你在问什么。{Binding}本身将始终绑定到DataContext。因此,如果您在ItemTemplate中,那么它将绑定到集合中的一个元素。好吧,对我来说,{Binding}将自身绑定到集合中的DataContext并不是很明显。对我来说,在列表中的当前datacontext上运行看起来很自然。但我现在明白了,谢谢。
<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>
/// <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; }
}