如何注册文本框文本的附件属性,以便DataGrid可以在更改上更新



我有一个文本框和一个类似的datagrid:

<Page
    TextElement.FontSize="14" FontFamily="Segoe UI"
    Title="Delivery View">
    <Page.Resources>
        <xcdg:DataGridCollectionViewSource x:Key="firstNameDataSource" 
                                           Source="{Binding Path=Accessor.Views[FirstNameView].SourceCollection}"
                                           AutoFilterMode="And"
                                           DistinctValuesConstraint="Filtered">
            <xcdg:DataGridCollectionViewSource.ItemProperties>
                <xcdg:DataGridItemProperty Name="FirstName" CalculateDistinctValues="False"/>
            </xcdg:DataGridCollectionViewSource.ItemProperties>            
        </xcdg:DataGridCollectionViewSource>
    </Page.Resources>
    <ScrollViewer Name="pendingScroll" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
        <DockPanel Name="pnlMainPanel" LastChildFill="True" Style="{StaticResource panelBackground}">
            <Grid Margin="15">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" FontSize="18" Text="Pending Guests" Margin="0,1,3,1" Foreground="SteelBlue" HorizontalAlignment="Left"/>
                <TextBox Name="txtFirstNameFilter" Grid.Row="1" >                    
                </TextBox>
                    <xcdg:DataGridControl x:Name="gridPendingGuests" Margin="5,0,5,1"
                                  HorizontalAlignment="Stretch"
                                  VerticalAlignment="Stretch"
                                  MinHeight="100"
                                  MinWidth="200"
                                CellEditorDisplayConditions="None"
                                EditTriggers="None"
                                ItemScrollingBehavior="Immediate"
                                AutoCreateColumns="False"
                                SelectionMode="Single"
                                NavigationBehavior="RowOnly"
                                ItemsSource="{Binding Source={StaticResource firstNameDataSource}}">
                        <xcdg:DataGridControl.View>
                            <xcdg:TableView ShowRowSelectorPane="False"/>
                        </xcdg:DataGridControl.View>
                        <xcdg:DataGridControl.Columns>
                            <xcdg:Column x:Name="FirstName" FieldName="FirstName" Title="First Name" Width="150" />
                        </xcdg:DataGridControl.Columns>
                        <i:Interaction.Behaviors>
                            <utils:UpdateDataGridOnTextboxChange/>
                        </i:Interaction.Behaviors>
                    </xcdg:DataGridControl>
            </Grid>
        </DockPanel>
    </ScrollViewer>
</Page>

在数据杂志中,您有一个名字的集合。这很好。显示很好。如您所见,我添加了一个Interactions.Behavior类,该类当前在用户使用鼠标命中数据杂志时,用硬编码值处理过滤器。过滤效果很好。如果有" John"的名字,则将该记录从视图中删除,并留下所有其他记录。

这是该代码:

using System.Windows.Interactivity;
using System.Windows;
using Xceed.Wpf.DataGrid;
using System;
namespace Some.Namespace.Behaviors
{
    public class UpdateDataGridOnTextboxChange : Behavior<DataGridControl>
    {
        protected override void OnAttached()
        {
            AssociatedObject.MouseUp += AssociatedObjectOnMouseUp;
            base.OnAttached();
        }
        protected override void OnDetaching()
        {
            AssociatedObject.MouseUp -= AssociatedObjectOnMouseUp;
            base.OnDetaching();
        }
        private void AssociatedObjectOnMouseUp(object sender, RoutedEventArgs routedEventArgs)
        {
            var items = AssociatedObject.Items;
            items.Filter = CollectionFilter;
        }
        private bool CollectionFilter(object item)
        {
            System.Data.DataRow dr = item as System.Data.DataRow;
            //set the ItemArray as Guest
            Guest guest = SetGuest(dr);
            if (guest.FirstName.Equals("John"))
            {
                return false;
            }
            return true;            
        }
        private Guest SetGuest(System.Data.DataRow dr)
        {
            Guest guest = new Guest();
            guest.FirstName = dr.ItemArray[0].ToString();
            return guest;
        } 
        public class Guest
        {
            public string FirstName { get; set; }
        }
    }
}

这是按预期工作的。同样,当用户单击数据杂志时,过滤器将用" John"的名字过滤出用户。

我想发生的事情是让用户能够在txtfirstnamefilter textbox中键入一个名字和数据杂志,然后滤除包含名字中文本的记录,使其可见,而其他的记录则没有。不可见的名字。

我可以做到的是使用文本框的文本变成属性的附加属性?这是一个问题,因为我不知道如何执行附件属性,然后确保该附件属性实际上更改时,请调用AssocledObjectonMouseup方法来运行过滤。

System.Windows.Interactivity.Behavior<T>从dependencyObject继承。因此,给它一个依赖性属性并约束。

public class UpdateDataGridOnTextboxChange : Behavior<DataGrid>
{
    #region FilterValue Property
    public String FilterValue
    {
        get { return (String)GetValue(FilterValueProperty); }
        set { SetValue(FilterValueProperty, value); }
    }
    public static readonly DependencyProperty FilterValueProperty =
        DependencyProperty.Register(nameof(FilterValue), typeof(String), typeof(UpdateDataGridOnTextboxChange),
            new FrameworkPropertyMetadata(null, FilterValue_PropertyChanged));
    protected static void FilterValue_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (d as UpdateDataGridOnTextboxChange).OnFilterValueChanged(e.OldValue);
    }
    private void OnFilterValueChanged(object oldValue)
    {
        //  Do whatever you do to update the filter
        //  I did a trace just for testing. 
        System.Diagnostics.Trace.WriteLine($"Filter value changed from '{oldValue}' to '{FilterValue}'");
    }
    #endregion FilterValue Property
    /*****************************************
         All your code here
     *****************************************/
}

xaml:

            <i:Interaction.Behaviors>
                <utils:UpdateDataGridOnTextboxChange
                    FilterValue="{Binding Text, ElementName=txtFirstNameFilter}"
                    />
            </i:Interaction.Behaviors>

您应该重命名。它与文本框无关。您可以将FilterValue绑定到ViewModel属性,或Combobox中的选定值,或其他。


更新

op在文本框失去焦点时仅更新FilterValue的绑定而遇到麻烦。这不是我看到的,但我不知道两者之间有什么不同。

没有Binding的任何UpdateTargetTrigger属性,但是当两个都是依赖关系对象的依赖关系属性时,您可以交换源和目标。这对我有用:

<TextBox 
    x:Name="txtFirstNameFilter"
    Text="{Binding FilterValue, ElementName=DataGridFilterThing, UpdateSourceTrigger=PropertyChanged}"
    />
<!-- snip snip snip -->
<i:Interaction.Behaviors>
    <local:UpdateDataGridOnTextboxChange
        x:Name="DataGridFilterThing"
        />
</i:Interaction.Behaviors>

最新更新