У меня есть два 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
Не могли бы вы разместить код поведения, пожалуйста? Вероятно, вы используете некоторые статические значения в этом поведении. – ibebbs
Я добавил код поведения. Я думаю, что нет ничего статического. –