How do I use WPF bindings with RelativeSource?

前端 未结 13 2000
执念已碎
执念已碎 2020-11-22 03:00

How do I use RelativeSource with WPF bindings and what are the different use-cases?

相关标签:
13条回答
  • 2020-11-22 03:41

    If you want to bind to another property on the object:

    {Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
    

    If you want to get a property on an ancestor:

    {Binding Path=PathToProperty,
        RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
    

    If you want to get a property on the templated parent (so you can do 2 way bindings in a ControlTemplate)

    {Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
    

    or, shorter (this only works for OneWay bindings):

    {TemplateBinding Path=PathToProperty}
    
    0 讨论(0)
  • 2020-11-22 03:42
    Binding RelativeSource={
        RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemType}
    }
    ...
    

    The default attribute of RelativeSource is the Mode property. A complete set of valid values is given here (from 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.

    0 讨论(0)
  • 2020-11-22 03:47

    I just posted another solution for accessing the DataContext of a parent element in Silverlight that works for me. It uses Binding ElementName.

    0 讨论(0)
  • 2020-11-22 03:48

    It's worthy of note that for those stumbling across this thinking of Silverlight:

    Silverlight offers a reduced subset only, of these commands

    0 讨论(0)
  • 2020-11-22 03:50

    I created a library to simplify the binding syntax of WPF including making it easier to use RelativeSource. Here are some examples. Before:

    {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}
    

    After:

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

    Here is an example of how method binding is simplified. Before:

    // 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}
    

    After:

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

    You can find the library here: http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html

    Note in the 'BEFORE' example that I use for method binding that code was already optimized by using RelayCommand which last I checked is not a native part of WPF. Without that the 'BEFORE' example would have been even longer.

    0 讨论(0)
  • 2020-11-22 03:52

    This is an example of the use of this pattern that worked for me on empty datagrids.

    <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>
    
    0 讨论(0)
提交回复
热议问题