WPF Binding Note
引言
记录绑定相关的知识点
绑定最初的样子
WPF中的数据绑定主要是将自定义的ViewModel的可通知属性和命令绑定到控件的依赖与附加属性。对于绑定的数据源,在没有对绑定属性/命令做特殊的声明时会自动根据元素树找到当前最近的DataContext,直到找到文件(Window、Page等节点)结束。
- XAML中不指定数据源
<Image Stretch="Fill" Source="{Binding CurrentBackground}"/>
也可以写成
<Image Stretch="Fill" Source="{Binding Path = CurrentBackground}"/>
ViewModel
public partial class BackgroundViewModel : ViewModelBase
{
public BackgroundViewModel()
{
SelectedCommand = new RelayCommand<Picture>(p =>
{
CurrentBackground = p.Source;
});
}
public ICommand SelectedCommand { get; private set; }
private string currentBackground;
public string CurrentBackground
{
get { return currentBackground; }
set { currentBackground = value; RaisePropertyChanged(); }
}
}
后台赋值DataContext
public BackgroundView()
{
InitializeComponent();
DataContext = new BackgroundViewModel() { CurrentBackground = pictures[0]?.Source };
}
Item控件中绑定自身
在使用ListView ListBox等集合的控件时,每个子项的绑定通常都直接通过Path=Property的方式将子项属性绑定到某个UI控件上。但是当需要直接将子项绑定到某个参数上时,以下方法来实现。
WPF中"{Binding Path=.}“即是本身,而在UWP中则可简写为”{Binding}"
<DataTemplate DataType="{x:Type personalization:Picture}">
<Border Margin="3">
<uicore:CommandControl Command="{Binding DataContext.SelectedCommand,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl},AncestorLevel=1}}" CommandParameter="{Binding Path=.}">
<Image Source="{Binding Source}"/>
</uicore:CommandControl>
</Border>
</DataTemplate>
绑定数据源相对关系RelativeSource
Mode:描述与绑定目标的位置相对的绑定源位置。
Mode | value | Description |
---|---|---|
FindAncestor | 3 | 引用数据绑定元素的父链中的上级。 这可用于绑定到特定类型的上级或其子类。 如果您要指定 AncestorType 和/或 AncestorLevel,可以使用此模式。 |
PreviousData | 0 | 允许在当前显示的数据项列表中绑定上一个数据项(不是包含数据项的控件)。 |
Self | 2 | 引用正在其上设置绑定的元素,并允许你将该元素的一个属性绑定到同一元素的其他属性上。 |
TemplatedParent | 1 | 引用应用了模板的元素,其中此模板中存在数据绑定元素。 这类似于设置 TemplateBindingExtension,并仅当 Binding 在模板中时适用。 |
写法:
(1)
<DataTemplate DataType="{x:Type personalization:Picture}">
<Border Margin="3">
<uicore:CommandControl Command="{Binding DataContext.SelectedCommand,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl},AncestorLevel=1}}" CommandParameter="{Binding Path=.}">
<Image Source="{Binding Source}"/>
</uicore:CommandControl>
</Border>
</DataTemplate>
(2)
<DataTemplate DataType="{x:Type personalization:Picture}">
<Border Margin="3">
<uicore:CommandControl Command="{Binding DataContext.SelectedCommand,RelativeSource={RelativeSource AncestorType={x:Type UserControl},AncestorLevel=1,Mode=FindAncestor}}" CommandParameter="{Binding Path=.}">
<Image Source="{Binding Source}"/>
</uicore:CommandControl>
</Border>
</DataTemplate>
- FindAncestor
有时候我们不确定作为数据源的对象叫什么名字,但知道作为绑定源与UI布局有相对的关系。
<DataTemplate DataType="{x:Type personalization:Picture}">
<Border Margin="3">
<uicore:CommandControl Command="{Binding DataContext.SelectedCommand,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl},AncestorLevel=1}}" CommandParameter="{Binding Path=.}">
<Image Source="{Binding Source}"/>
</uicore:CommandControl>
</Border>
</DataTemplate>
属性名 | 含义 |
---|---|
AncestorType | 要查找的上级节点的类型 |
AncestorLevel | 以 FindAncestor 模式获取或设置要查找的上级级别。使用 1 指示最靠近绑定目标元素的项。 |
- PreviousData
使用该方式将使源元素成为模板目标类型—即TargetType;如果该绑定是在模板中,那么它的作为范围也只限于该模板。
- Self
一般用于绑定自身元素的其它属性。例如:
<Slider Interval="1"
TickFrequency="1"
IsSnapToTickEnabled="True"
Minimum="0" Maximum="100"
ToolTip="{Binding Value , RelativeSource ={ RelativeSource Self}}"/>
- TemplatedParent
WPF中存在两个名词:LogicalTree与VisualTree,他们是用来标记元素之间的树形结构关系。我们的每个视图区域都会对应一个完整的VisualTree,但LogicalTree并不仅仅只存在一个,可以认为完整VisualTree是由多个LogicalTree组成的。因此将各个LogicalTree连接在一起就需要使用到TemplatedParent。
TemplatedParent:模板(控件模板或者数据模板)绑定的父元素,在模板中使用。详细的内容可以看
这个哥们儿写的。