2016-09-13 6 views
0

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

<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 

Вы можете использовать атрибуты в модели Autocreate фильтры в 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

Не могли бы вы разместить код поведения, пожалуйста? Вероятно, вы используете некоторые статические значения в этом поведении. – ibebbs

+0

Я добавил код поведения. Я думаю, что нет ничего статического. –

ответ

0

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