Quik Bytes
Quik Bytes

Reputation: 29

How to bind AttachedProperty

I have created Attached Property, for learning purposes but can't get successful result.

 public class AQDatagridDependencyProperties: DependencyObject
{
    public static void SetCustomDataSource(AQDataGrid element, string value)
    {
        element.SetValue(CustomDataSourceProperty, value);
    }

    public static string GetCustomDataSource(AQDataGrid element)
    {
        return (string)element.GetValue(CustomDataSourceProperty);
    }

    // Using a DependencyProperty as the backing store for DataSource.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CustomDataSourceProperty =
        DependencyProperty.Register("CustomDataSource", typeof(string), typeof(AQDataGrid), new PropertyMetadata("obuolys"));

}

I've placed this attached property in my custom datagrid User Control which is implemented in UserView Page.

<Page x:Class="PDB.UsersView"
  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:PDB"
  xmlns:PDB ="clr-namespace:PDBapi;assembly=PDBapi"
  xmlns:Wpf ="clr-namespace:AQWpf;assembly=AQWpf"
  mc:Ignorable="d" 
  d:DesignHeight="450" d:DesignWidth="800"
  Title="Users"
  Name="Users"
  VisualBitmapScalingMode="LowQuality"

  >

<Page.DataContext>
    <PDB:UsersViewModel x:Name="vm"/>
</Page.DataContext>

<Grid VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling">
    <Wpf:AQDataGrid DataContext="{Binding AQDatagridViewModel}" Wpf:AQDatagridDependencyProperties.CustomDataSource="Something" />
</Grid>

Question is how to bind that attached property value inside Custom Datagrid User Control? Example:

<UserControl x:Class="AQWpf.AQDataGrid"
         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:AQWpf"
         xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
         mc:Ignorable="d"              
         Name="AQCustomDataGrid"

         >
<!--Custom Data grid Implementation-->

    <DataGrid x:Name="InstructionsDataGrid" 
              Grid.Row="1"
              DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=local:AQDataGrid}, Path=DataContext}"
              Style="{StaticResource OptimizedAGDatagrid}"
              ItemsSource="{Binding Data}"
              CurrentItem="{Binding SelectedObject, Mode=TwoWay}"
              CurrentColumn="{Binding CurrentColumn, Mode=TwoWay}"
              CurrentCell="{Binding CurrentCells, Mode=TwoWay}"  
              Tag="<----How to bind here? ---->}"
              >

Upvotes: 0

Views: 101

Answers (2)

BionicCode
BionicCode

Reputation: 29028

You were defining a simple DepencyProperty. You have to use the DependencyProperty.RegisterAttached method to register the DependencyProperty as an attached property.
Also the owner type must be set to the declaring class' type (typeof(AQDatagridDependencyProperties)) and not the attaching type (typeof(AQDataGrid)):

AQDatagridDependencyProperties.cs

public class AQDatagridDependencyProperties : DependencyObject
{
  public static readonly DependencyProperty CustomDataSourceProperty = DependencyProperty.RegisterAttached(
    "CustomDataSource",
    typeof(string),
    typeof(AQDatagridDependencyProperties),
    new FrameworkPropertyMetadata("obuolys", AQDatagridDependencyProperties.DebugPropertyChanged));

  private static void DebugPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
    var oldValue = e.OldValue; // Set breakpoints here
    var newValue = e.NewValue; // in order to track property changes 
  }

  public static void SetCustomDataSource(DependencyObject attachingElement, string value)
  {
    attachingElement.SetValue(CustomDataSourceProperty, value);
  }

  public static string GetCustomDataSource(DependencyObject attachingElement)
  {
    return (string) attachingElement.GetValue(CustomDataSourceProperty);
  }
}

Usage

<AQDataGrid AQDatagridDependencyProperties.CustomDataSource="Something" />

Inside the AQDataGrid control:

<DataGrid x:Name="InstructionsDataGrid" 
          Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=AQDataGrid}, Path=(AQDatagridDependencyProperties.CustomDataSource)}" />

Upvotes: 1

Clemens
Clemens

Reputation: 128136

Your attached property declaration is incorrect. You must call RegisterAttached instead of Register, and the third argument passed to the method must by the type of the class that declares the property.

Besides that, the declaring class does not need to be derived from DependencyObject, and could even be declared static:

public static class AQDatagridDependencyProperties
{
    public static readonly DependencyProperty CustomDataSourceProperty =
         DependencyProperty.RegisterAttached( // here
             "CustomDataSource",
             typeof(string),
             typeof(AQDatagridDependencyProperties), // and here
             new PropertyMetadata("obuolys"));

    public static string GetCustomDataSource(AQDataGrid element)
    {
        return (string)element.GetValue(CustomDataSourceProperty);
    }

    public static void SetCustomDataSource(AQDataGrid element, string value)
    {
        element.SetValue(CustomDataSourceProperty, value);
    }
} 

You would set that property like

 <local:AQDataGrid local:AQDatagridDependencyProperties.CustomDataSource="something" >

and bind to it by an expression like

Tag="{Binding Path=(local:AQDatagridDependencyProperties.CustomDataSource),
              RelativeSource={RelativeSource AncestorType=UserControl}}"

As a note, you would typically declare the property as a regular dependency property in the AQDataGrid class.

Upvotes: 1

Related Questions