c# - 绑定 Text 属性以在作为 DataTemplate 的一部分的弹出窗口中进行过滤不起作用
问题描述
我有一个显示数据网格的应用程序。但是数据已经变大了,我想将过滤器合并到一些行中。我已经为我的标题创建了一个 DataTemplate:
<DataGrid>
<DataGrid.Resources>
...
<DataTemplate x:Key="HeaderTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentControl Content="{Binding}" VerticalAlignment="Center"/>
<ToggleButton Name="FilterButton" Grid.Column="1" Content="▼" Margin="2, 1, 1, 1" Padding="1, 0"/>
<Popup IsOpen="{Binding ElementName=FilterButton, Path=IsChecked}" PlacementTarget="{Binding ElementName=FilterButton}" StaysOpen="False">
<Border Background="White" Padding="3">
<TextBox Text={Binding PetNameFilterSearchBox, Mode=TwoWay} Width="300"/> <!--The Text Box I want to bind-->
</Border>
</Popup>
</Grid>
</DataTemplate>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Width="6*" Header="Pet Name" Binding="{Binding PetName}" ElementStyle="{DynamicResource DataGridTextColumnWrap}" HeaderTemplate="{StaticResource HeaderTemplate}"/>
</DataGrid.Columns>
</DataGrid>
到目前为止,它所做的是在标题文本旁边显示一个按钮,当您单击它时,会出现一个包含文本框的小弹出窗口。期望的效果是用户可以在文本框中键入,数据将根据键入的内容进行过滤。
在我的视图模型中,我已经有了要用于绑定的过滤器文本框属性:
public string PetNameFilterSearchBox
{
get
{
return _petNameFilterSearchBox;
}
set
{
_petNameFilterSearchBox = value;
RaisePropertyChanged(nameof(PetNameFilterSearchBox));
FilterData(); //As you're writing
}
}
private string _petNameFilterSearchBox = string.Empty;
public CollectionView PetDataFilterView { get; set; }
public bool OnFilterTriggered(object item)
{
if (item is AvailablePetInfo petInfo)
{
var pet_name = PetNameFilterSearchBox;
if (pet_name != string.Empty)
return (petInfo.DisplayName.Contains(pet_name));
}
return true;
}
public void FilterData()
{
CollectionViewSource.GetDefaultView(AvailablePetInfo).Refresh();
}
//Constructor
public PetInfoViewModel()
{
AvailablePetInfo = GetPetInfo();//gets the list
ContactFilterView = (CollectionView)CollectionViewSource.GetDefaultView(AvailablePetInfo);
ContactFilterView.Filter = OnFilterTriggered;
}
当我运行我的代码时,我看到标题旁边的小按钮,我单击它并看到文本框。但是当我开始打字时,我看不到我的数据网格更新。我在我的 PetNameFilterSearchBox 中设置了一些断点,我发现当我开始输入时它没有被击中。这告诉我绑定有问题。有人可以告诉我我做错了什么吗?
解决方案
您的问题是其中之一DataContext
。
我将假设PetNameFilterSearchBox
是Window
托管的属性,并且在级别设置DataGrid
了适当的属性。DataContext
Window
通常,DataContext
由子元素继承,因此设置DataContext
forWindow
将为它的所有子元素设置它。但是一旦你开始使用DataTemplate
s,情况就会改变。
在 aDataTemplate
中,根DataContext
始终是正在显示的数据对象。在您的情况下,这就是 string "Pet Name"
。这就是为什么你可以把它放在<ContentControl Content="{Binding}"/>
里面DataTemplate
并让它显示"Pet Name"
。
缺点是你不能把<TextBox Text="{Binding PetNameFilterSearchBox}"/>
它绑定到Window
,因为它DataContext
被DataTemplate
.
通常,您可以使用 来解决DataTemplate
DataContext
问题RelativeSource
,您可以使用它来遍历可视化树并找到另一个要绑定的源。但这在 a 中不起作用,Popup
因为 aPopup
实际上不是Window
' 的可视化树的一部分。
什么会起作用ElementName
:
<TextBox Text="{Binding PetNameFilterSearchBox, Mode=TwoWay, ElementName=W}" Width="300"/>
在上面的示例中,我设置了我的Window
Name="W"
.
推荐阅读
- python - 将字符串转换为带有模式的几个变量
- c# - 列加载事件以设置子级边距
- ffmpeg - ffmpeg 到 Youtube Live 停止工作。ffmpeg 继续运行
- html - 将禁用属性传递给子组件中的 HTML 元素不起作用
- intellij-idea - 带有@GrailsCompileStatic 注解的Grails GORM 类在静态映射闭包表、版本、autoTimestamp 中显示为未解析符号
- java - 选定的值保留保存在带有单选按钮 Android 的 Dialogfragment 中
- java - 使用 AsyncTask 在 Android 中按时间间隔运行 HTTPS 请求
- python-3.x - 每次运行时,我的 python 脚本中的一段代码都会出错
- python - Python中的多值行数
- javascript - 在JS中剪切字符串的开头和结尾