Wpf 如何注册Textbox文本的附加属性,以便Datagrid可以在更改时更新

Wpf 如何注册Textbox文本的附加属性,以便Datagrid可以在更改时更新,wpf,xaml,behavior,Wpf,Xaml,Behavior,我有一个文本框和一个数据网格,如下所示: <Page TextElement.FontSize="14" FontFamily="Segoe UI" Title="Delivery View"> <Page.Resources> <xcdg:DataGridCollectionViewSource x:Key="firstNameDataSource"

我有一个文本框和一个数据网格,如下所示:

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

在datagrid中,您有一组名字。这很好用。显示器很好。如您所见,我添加了Interactions.Behavior类,当用户用鼠标单击datagrid时,该类当前处理带有硬编码值的过滤器。过滤效果很好。如果有“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; }
        }

    }
}
使用System.Windows.Interactivity;
使用System.Windows;
使用Xceed.Wpf.DataGrid;
使用制度;
namespace.Some.namespace.Behaviors
{
公共类UpdateDagTagRidContextBoxChange:行为
{
受保护的覆盖无效附加()
{
AssociatedObject.MouseUp+=AssociatedObjectOnMouseUp;
base.onatached();
}
附加时受保护的覆盖无效()
{
AssociatedObject.MouseUp-=AssociatedObjectOnMouseUp;
base.OnDetaching();
}
private void AssociatedObjectOnMouseUp(对象发送方,RoutedEventTargets RoutedEventTargets)
{
var items=AssociatedObject.items;
items.Filter=CollectionFilter;
}
私有布尔集合筛选器(对象项)
{
System.Data.DataRow dr=项目为System.Data.DataRow;
//将ItemArray设置为Guest
Guest-Guest=SetGuest(dr);
if(guest.FirstName.Equals(“John”))
{
返回false;
}
返回true;
}
私人来宾SetGuest(System.Data.DataRow dr)
{
来宾=新来宾();
guest.FirstName=dr.ItemArray[0].ToString();
回访客人;
} 
公务舱客人
{
公共字符串名{get;set;}
}
}
}
这正如预期的那样有效。同样,当用户单击datagrid时,过滤器会过滤掉名为“John”的用户

我希望用户能够在txtFirstNameFilter文本框和datagrid中键入名字,然后过滤包含名字文本的记录,使其可见,而其他没有名字的记录则不可见

我可以使用Textbox TextChanged属性的附加属性来执行此操作?这是一个问题,因为我不知道如何处理附加属性,以及如何确保当附加属性实际更改时,调用AssociatedObjectOnMouseUp方法来运行筛选。

继承自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

     *****************************************/
}

ElementName是XAML中文本框的名称吗?因此,在本例中,它将是FilterValue=“{Binding Text,ElementName=txtFirstNameFilter}”@crackedcornjimmy是的,在您的案例中就是这样。更新了,我快到了。我可以在txtFirstNameFilter文本框中键入一个值,但什么也没有发生。但是,当我离开视图时(无论是关闭应用程序还是只是移动应用程序中的其他位置),代码就会触发,我可以过滤数据网格。有什么方法可以触发过滤代码在文本框中的KeyUp上运行吗?对我来说,绑定是在文本框中每次击键时更新
FilterValue
。您是否在
FilterValue\u PropertyChanged
中设置了断点?可以将FilterValue和TextBox.Text绑定到viewmodel属性,并将
UpdateSourceTrigger=PropertyChanged
添加到
TextBox.Text的绑定中?如果我告诉你我没有viewmodel怎么办?
            <i:Interaction.Behaviors>
                <utils:UpdateDataGridOnTextboxChange
                    FilterValue="{Binding Text, ElementName=txtFirstNameFilter}"
                    />
            </i:Interaction.Behaviors>
<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>