代码之家  ›  专栏  ›  技术社区  ›  David Schmitt

如何将WPF绑定与RelativeSource一起使用?

  •  541
  • David Schmitt  · 技术社区  · 16 年前

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

    14 回复  |  直到 16 年前
        1
  •  719
  •   Guge    8 年前

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

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

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

    {TemplateBinding Path=PathToProperty}
    
        2
  •  125
  •   Drew Noakes    16 年前
    Binding RelativeSource={
        RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemType}
    }
    ...
    

    RelativeSource Mode from MSDN

        3
  •  119
  •   Jeffrey Knight    13 年前

    enter image description here

        4
  •  40
  •   lasitha edirisooriya    12 年前

    <Rectangle Fill="Red" Name="rectangle" 
                        Height="100" Stroke="Black" 
                        Canvas.Top="100" Canvas.Left="100"
                        Width="{Binding ElementName=rectangle,
                        Path=Height}"/>
    

    <Rectangle Fill="Red" Height="100" 
                       Stroke="Black" 
                       Width="{Binding RelativeSource={RelativeSource Self},
                       Path=Height}"/>
    

     <TextBlock Width="{Binding RelativeSource={RelativeSource Self},
                       Path=Parent.ActualWidth}"/>
    

        5
  •  34
  •   Brad Larson    11 年前

    his article here

    <Rectangle Fill="Red" Name="rectangle" 
                    Height="100" Stroke="Black" 
                    Canvas.Top="100" Canvas.Left="100"
                    Width="{Binding ElementName=rectangle,
                    Path=Height}"/>
    

    <Rectangle Fill="Red" Height="100" 
                   Stroke="Black" 
                   Width="{Binding RelativeSource={RelativeSource Self},
                   Path=Height}"/>
    

     <TextBlock Width="{Binding RelativeSource={RelativeSource Self},
                   Path=Parent.ActualWidth}"/>
    

    <Canvas Name="Parent0">
        <Border Name="Parent1"
                 Width="{Binding RelativeSource={RelativeSource Self},
                 Path=Parent.ActualWidth}"
                 Height="{Binding RelativeSource={RelativeSource Self},
                 Path=Parent.ActualHeight}">
            <Canvas Name="Parent2">
                <Border Name="Parent3"
                Width="{Binding RelativeSource={RelativeSource Self},
               Path=Parent.ActualWidth}"
               Height="{Binding RelativeSource={RelativeSource Self},
                  Path=Parent.ActualHeight}">
                   <Canvas Name="Parent4">
                   <TextBlock FontSize="16" 
                   Margin="5" Text="Display the name of the ancestor"/>
                   <TextBlock FontSize="16" 
                     Margin="50" 
                Text="{Binding RelativeSource={RelativeSource  
                           FindAncestor,
                           AncestorType={x:Type Border}, 
                           AncestorLevel=2},Path=Name}" 
                           Width="200"/>
                    </Canvas>
                </Border>
            </Canvas>
         </Border>
       </Canvas>
    

    <Window.Resources>
    <ControlTemplate x:Key="template">
            <Canvas>
                <Canvas.RenderTransform>
                    <RotateTransform Angle="20"/>
                    </Canvas.RenderTransform>
                <Ellipse Height="100" Width="150" 
                     Fill="{Binding 
                RelativeSource={RelativeSource TemplatedParent},
                Path=Background}">
    
                  </Ellipse>
                <ContentPresenter Margin="35" 
                      Content="{Binding RelativeSource={RelativeSource  
                      TemplatedParent},Path=Content}"/>
            </Canvas>
        </ControlTemplate>
    </Window.Resources>
        <Canvas Name="Parent0">
        <Button   Margin="50" 
                  Template="{StaticResource template}" Height="0" 
                  Canvas.Left="0" Canvas.Top="0" Width="0">
            <TextBlock FontSize="22">Click me</TextBlock>
        </Button>
     </Canvas>
    

        6
  •  23
  •   Peter Mortensen icecrime    7 年前

    RelativeSource properties

    enum

    value=0 property

    value=1 templates control

    ControlTemplate

      <ControlTemplate>
            <CheckBox IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
     </ControlTemplate>
    

    value=2 self

    checkbox CommandParameter Command CheckBox

    <CheckBox ...... CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=IsChecked}" />
    

    value=3 Visual Tree

    records grid header

    <CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}, Path=DataContext.IsHeaderChecked, Mode=TwoWay}" />
    

    FindAncestor

    RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}
    

    visual tree

    RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid, AncestorLevel=1}}
    

    RelativeSource binding

    Here is a reference link

        7
  •  18
  •   Bob King    16 年前

    <Binding RelativeSource="{RelativeSource TemplatedParent}"/>
    

    {Binding RelativeSource={RelativeSource TemplatedParent}}
    
        8
  •  13
  •   Matthew Black    15 年前

        9
  •  13
  •   Luis Perez    12 年前

    {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

    RelayCommand

        10
  •  12
  •   Peter Mortensen icecrime    7 年前

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

    Binding Relative Source in code Behind

    RelativeSource Class

        11
  •  10
  •   Community CDub    8 年前

    another solution Binding ElementName

        12
  •  9
  •   Peter Mortensen icecrime    7 年前

    Mode=FindAncestor

    Command="{Binding Path=DataContext.CommandProperty, RelativeSource={...}}"
    

        13
  •  8
  •   Edd    10 年前

    <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>
    
        14
  •  4
  •   Contango    7 年前

    [WPF] How to bind to data when the DataContext is not inherited

    his article

    comment directly on his blog post

    <DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                    Visibility="{Binding ShowPrice,
                    Converter={StaticResource visibilityConverter}}"/>
    

    <DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                    Visibility="{Binding DataContext.ShowPrice,
                    Converter={StaticResource visibilityConverter},
                    RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>
    

    <DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                    Visibility="{Binding IsChecked,
                    Converter={StaticResource visibilityConverter},
                    ElementName=chkShowPrice}"/>
    

    public class BindingProxy : Freezable
    {
        #region Overrides of Freezable
    
        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
        }
    
        #endregion
    
        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
    }
    

    <DataGrid.Resources>
        <local:BindingProxy x:Key="proxy" Data="{Binding}" />
    </DataGrid.Resources>
    

    <DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                    Visibility="{Binding Data.ShowPrice,
                    Converter={StaticResource visibilityConverter},
                    Source={StaticResource proxy}}"/>