Неподеленное поведение WPF

У меня есть две DataGrids в Window, и я использую поведение Blend для создания фильтров в заголовках столбцов.

<DataGrid>
  <i:Interaction.Behaviors>
    <v:ColumnBehavior/>
  </i:Interaction.Behaviors>
</DataGrid>
<DataGrid>
  <i:Interaction.Behaviors>
    <v:ColumnBehavior/>
  </i:Interaction.Behaviors>
</DataGrid>  

Проблема в том, что экземпляр этого поведения так или иначе является общим для обеих DataGrids, поэтому, если вы установите фильтр для первой DataGrid, он будет установлен автоматически во второй DataGrid и наоборот. Мне нужно, чтобы эти фильтры (поведения) были независимыми. Из того, что я прочитал, невозможно добиться стилями.

Класс поведения:

Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations
Imports System.IO
Imports System.Text
Imports System.Windows.Controls.Primitives
Imports System.Windows.Interactivity
Imports System.Windows.Markup
Namespace View
  Friend Class ColumnBehavior
    Inherits Behavior(Of DataGrid)
    Protected Overrides Sub OnAttached()
      MyBase.OnAttached()
      AddHandler AssociatedObject.AutoGeneratingColumn, AddressOf OnAutoGeneratingColumn
    End Sub
    Protected Sub OnAutoGeneratingColumn(sender As Object, e As DataGridAutoGeneratingColumnEventArgs)
      If e.PropertyDescriptor IsNot Nothing Then
        Dim descriptor = DirectCast(e.PropertyDescriptor, PropertyDescriptor)
        Dim customString = DirectCast(descriptor.Attributes(GetType(CustomStringAttribute)), CustomStringAttribute)
        If customString IsNot Nothing Then
          Dim unitType = DirectCast([Enum].Parse(GetType(DataGridLengthUnitType), customString.Value), DataGridLengthUnitType)
          e.Column.Width = New DataGridLength(1, unitType)
        End If
        Dim display = DirectCast(descriptor.Attributes(GetType(DisplayAttribute)), DisplayAttribute)
        If display IsNot Nothing Then
          e.Cancel = (Not display.GetAutoGenerateField().GetValueOrDefault(True))
          e.Column.Header = display.GetShortName()
          Dim headerStyle = e.Column.HeaderStyle
          If headerStyle Is Nothing Then headerStyle = New Style(GetType(DataGridColumnHeader))
          headerStyle.Setters.Add(New Setter(ToolTipService.ToolTipProperty, display.GetDescription()))
          e.Column.HeaderStyle = headerStyle
          If display.GetAutoGenerateFilter().GetValueOrDefault(False) Then
            Dim comboBoxBinding = DirectCast(descriptor.Attributes(GetType(ComboBoxBindingAttribute)), ComboBoxBindingAttribute)
            If comboBoxBinding IsNot Nothing Then
              Dim bindingString = "{{Binding {0}, RelativeSource={{RelativeSource FindAncestor, AncestorType={{x:Type Window}}}}}}"
              Dim dataTemplateXaml = <DataTemplate>
                                       <Grid>
                                         <Grid.ColumnDefinitions>
                                           <ColumnDefinition Width="*"/>
                                           <ColumnDefinition Width="Auto"/>
                                         </Grid.ColumnDefinitions>
                                         <TextBlock
                                           Text="{Binding Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"
                                           Margin="0,0,4,0"
                                           VerticalAlignment="Center"
                                           Grid.Column="0"/>
                                         <ComboBox
                                           IsReadOnly="True"
                                           ItemsSource=<%= String.Format(bindingString, comboBoxBinding.ItemsSource) %>
                                           SelectedItem=<%= String.Format(bindingString, comboBoxBinding.SelectedItem) %>
                                           Grid.Column="1"
                                           SelectedIndex="0"/>
                                       </Grid>
                                     </DataTemplate>
              Dim headerTemplate As DataTemplate
              Using dataTemplateReader As New MemoryStream(Encoding.UTF8.GetBytes(dataTemplateXaml.ToString()))
                Dim context As New ParserContext
                context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation")
                context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml")
                headerTemplate = DirectCast(XamlReader.Load(dataTemplateReader, context), DataTemplate)
              End Using
              e.Column.HeaderTemplate = headerTemplate
            End If
          End If
        End If
        Dim displayFormat = DirectCast(descriptor.Attributes(GetType(DisplayFormatAttribute)), DisplayFormatAttribute)
        If displayFormat IsNot Nothing Then
          DirectCast(e.Column, DataGridBoundColumn).Binding.StringFormat = displayFormat.DataFormatString
        End If
      End If
    End Sub
    Protected Overrides Sub OnDetaching()
      MyBase.OnDetaching()
      RemoveHandler AssociatedObject.AutoGeneratingColumn, AddressOf OnAutoGeneratingColumn
    End Sub
  End Class
End Namespace  

Атрибуты в модели используются для автоматического создания фильтров в DataGrid:

<Display(ShortName:="Meeting", Description:="Meeting code", AutoGenerateField:=True, AutoGenerateFilter:=True)>
    <ComboBoxBinding("DataContext.MeetingCodes", "DataContext.TasksMeetingCodeFilter")>
    <CustomString("SizeToCells")>
    Public Property TaskMeetingCode As String Implements ITaskView.TaskMeetingCode

1 ответ

Проблема решена. Есть два экземпляра класса поведения, как и должно быть, но оба экземпляра привязаны к одному и тому же свойству в viewmodel...

Другие вопросы по тегам