Как связать AttachedProperty - PullRequest
       51

Как связать AttachedProperty

0 голосов
/ 30 января 2020

Я создал Attached Property, для целей обучения, но не могу получить успешный результат.

 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"));

}

Я поместил это присоединенное свойство в свой пользовательский элемент управления сеткой данных, который реализован на странице UserView.

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

Вопрос в том, как связать значение этого присоединенного свойства в пользовательском элементе управления DataGrid? Пример:

<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? ---->}"
              >

Ответы [ 2 ]

1 голос
/ 30 января 2020

Ваша декларация о недвижимости неверна. Вы должны вызвать RegisterAttached вместо Register, и третий аргумент, передаваемый методу, должен указывать тип класса, который объявляет свойство.

Кроме того, объявивший класс не нужно выводить из DependencyObject, и даже может быть объявлен как stati c:

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);
    }
} 

Вы можете установить это свойство как

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

и связать его с помощью выражения типа

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

Как примечание, вы обычно объявляете свойство как обычное свойство зависимости в классе AQDataGrid.

1 голос
/ 30 января 2020

Вы определяли простое DepencyProperty. Вы должны использовать метод DependencyProperty.RegisterAttached, чтобы зарегистрировать DependencyProperty в качестве присоединенного свойства.
Также тип владельца должен быть установлен на тип объявления класса (typeof(AQDatagridDependencyProperties)), а не Тип подключения (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);
  }
}

Использование

<AQDataGrid AQDatagridDependencyProperties.CustomDataSource="Something" />

Внутри AQDataGrid управление:

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