我如何使用WPF绑定的RelativeSource,有哪些不同的用例?


当前回答

一些有用的小片段:

以下是如何主要在代码中做到这一点:

Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);

我很大程度上复制了这从绑定相对源在代码后面。

同样,就示例而言,MSDN页面也很不错:RelativeSource Class

其他回答

一些有用的小片段:

以下是如何主要在代码中做到这一点:

Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);

我很大程度上复制了这从绑定相对源在代码后面。

同样,就示例而言,MSDN页面也很不错:RelativeSource Class

Binding RelativeSource={
    RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemType}
}
...

RelativeSource的默认属性是Mode属性。这里给出了一组完整的有效值(来自MSDN):

PreviousData Allows you to bind the previous data item (not that control that contains the data item) in the list of data items being displayed. TemplatedParent Refers to the element to which the template (in which the data-bound element exists) is applied. This is similar to setting a TemplateBindingExtension and is only applicable if the Binding is within a template. Self Refers to the element on which you are setting the binding and allows you to bind one property of that element to another property on the same element. FindAncestor Refers to the ancestor in the parent chain of the data-bound element. You can use this to bind to an ancestor of a specific type or its subclasses. This is the mode you use if you want to specify AncestorType and/or AncestorLevel.

我创建了一个库来简化WPF的绑定语法,包括让它更容易使用RelativeSource。这里有一些例子。之前:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
{Binding Path=Text, ElementName=MyTextBox}

后:

{BindTo PathToProperty}
{BindTo Ancestor.typeOfAncestor.PathToProperty}
{BindTo Template.PathToProperty}
{BindTo #MyTextBox.Text}

下面是一个如何简化方法绑定的示例。之前:

// C# code
private ICommand _saveCommand;
public ICommand SaveCommand {
 get {
  if (_saveCommand == null) {
   _saveCommand = new RelayCommand(x => this.SaveObject());
  }
  return _saveCommand;
 }
}

private void SaveObject() {
 // do something
}

// XAML
{Binding Path=SaveCommand}

后:

// C# code
private void SaveObject() {
 // do something
}

// XAML
{BindTo SaveObject()}

你可以在这里找到图书馆:http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html

请注意,在我用于方法绑定的“BEFORE”示例中,代码已经通过使用RelayCommand进行了优化,我最后检查它不是WPF的本机部分。没有这个BEFORE的例子会更长。

这是我在空数据网格上使用该模式的一个示例。

<Style.Triggers>
    <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
        <Setter Property="Background">
            <Setter.Value>
                <VisualBrush Stretch="None">
                    <VisualBrush.Visual>
                        <TextBlock Text="We did't find any matching records for your search..." FontSize="16" FontWeight="SemiBold" Foreground="LightCoral"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>

值得注意的是,对于那些无意中发现Silverlight的想法的人:

Silverlight只提供了这些命令的一个简化子集