需要在WPF中通过XAML将窗口的DataContext指定为this很简单,如下所示:
<Window x:Class="MySystem.WindowProjectOptions"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MySystem"
mc:Ignorable="d"
Title="Project Options" Height="450" Width="400" ShowInTaskbar="False" SizeToContent="Height" WindowStartupLocation="CenterOwner" WindowStyle="ToolWindow"
x:Name="_this"
DataContext="{Binding ElementName=_this}"
>
<Grid>
</Grid>
</Window>
关键即在倒数第5和6行:
x:Name="_this"
DataContext="{Binding ElementName=_this}"
对于不是窗口而是页面Page的情况,则不能这样做,需要这样:
<Page x:Class="MySystem.PageUserAndRole"
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"
xmlns:local="clr-namespace:InfoStore"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="PageUserAndRole">
关键在倒数第二行:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
这样处理后,有时候我们在ListView中需要把某些控件的可选数据指向最上层容器它本身的某个属性,比如我给UserControl定义了下面这个列表,用来让用户在ListView中为每一行数据进行选择的:
public List<string> Categories { get; } =new List<string>() { "N/A", "Spare", "Server", "Workstation", "VPN Client", "Network Equipment", "Special" };
这个时候我们在ListView的数据模板中要这样定义:
<ListView x:Name="lvIPs" ItemsSource="{Binding Path=FilteredIPAssignments}" PreviewMouseDown="ListView_PreviewMouseDown" d:ItemsSource="{d:SampleData ItemCount=5}" >
<ListView.View>
<GridView>
<GridViewColumn x:Name="colCategoty" Width="80" Header="Category">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid Width="{Binding ElementName=colCategoty, Path=ActualWidth}">
<ComboBox ItemsSource="{Binding DataContext.Categories,
RelativeSource={RelativeSource AncestorType=UserControl}}" DisplayMemberPath="." Margin="0,0,12,0" SelectedIndex="{Binding UICategory}" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
注意重点在上面代码中ComboBox的ItemsSource的定义,因为我这里是定义在一个UserControl里,所以AncestorType是UserControl,如果这个定义在一个窗口里,则应该是Window而不是UserControl。
对于前面提到的第一种指定DataContext的方式(就是将窗口命名为_this的方式),这里ComboBox的ItemsSource的绑定就简单一些,这样写就行了:
<ComboBox ItemsSource="{Binding ElementName=_this, Path=Categories}" DisplayMemberPath="." Margin="0,0,12,0" SelectedIndex="{Binding UICategory}" />