从文本框使用MVVM正确的DataGrid搜索在WPF [英] Proper DataGrid search from TextBox in WPF using MVVM
问题描述
我是新来的MVVM模式,以及何时使用的背后code有点困惑。我有一个非常简单的形式,现在,它包括一个TextBox和一个DataGrid。我想是能够有改变的DataGrid基于文本框的选项。
I am new to the MVVM pattern, and a little confused on when to use Code Behind. I have a very simple form right now, that includes one TextBox, and one DataGrid. What I would like is to be able to have the DataGrid change its selected item based on the TextBox.
我在code背后做到了这一点,它使用以下code正常工作:
I have done this in Code Behind and it works fine using the following code:
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
for (int i = 0; i < dataGrid1.Items.Count; i++)
{
string cellContent = dtReferral.Rows[i][0].ToString();
try
{
if (cellContent != null && cellContent.Substring(0, textBox1.Text.Length).Equals(textBox1.Text))
{
object item = dataGrid1.Items[i];
dataGrid1.SelectedItem = item;
dataGrid1.ScrollIntoView(item);
//row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
break;
}
}
catch { }
}
}
现在,我只想强调在与文本框的文本开始DataGrid中的项目,并允许用户以preSS一个按钮来编辑选择的项目。
Now, I just want to highlight the Item in the Datagrid that starts with text in textbox, and allow the user to press a button to edit selected item.
什么情况下可以在其code文件背后,这个逻辑?或者,我需要通过某种结合做到这一点?如果我应该绑定做到这一点通过视图模型,任何方向将是AP preciated。谢谢你。
Is it okay to have this logic in the Code Behind file? Or would I need to do this through some sort of binding? If I should do this through the View Model with Binding, any direction would be appreciated. Thank you.
推荐答案
如果您只想强调从文本框的文本的单元格
你可以把一个 AttatchedProperty
为的DataGrid
来接受来自文本框的搜索值
和创建另一个 AttatchedProperty
为细胞
来指示匹配,你可以USEE在单元
的风格。然后,我们创建一个匹配 IMultiValueConverter
来检查细胞
值,以搜索文本
。
If you only want to highlight the cells with the text from the TextBox
you could make an AttatchedProperty
for the DataGrid
to accept your search value from the TextBox
and create another AttatchedProperty
for the Cell
to indicate a match that you can usee to set properties in the Cell
style. Then we create a IMultiValueConverter
to check the Cell
value for a match to the search Text
.
这样的可重复使用在其他项目上,你只需要在 AttachedProperties
和转换
This way its reusable on other projects as you only need the AttachedProperties
and Converter
绑定 AttachedProperty
SearchValue
你的文本框
文本
属性。
<DataGrid local:DataGridTextSearch.SearchValue="{Binding ElementName=SearchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}"
然后创建一个风格
为 DataGridCell
并为 AttachedProperty 二传手code>
IsTextMatch
使用 IMultiValueConverter
来返回,如果单元格文本相匹配的 SearchValue
Then create a Style
for DataGridCell
and create a Setter for the AttachedProperty
IsTextMatch
using the IMultiValueConverter
to return if the cells text matches the SearchValue
<Setter Property="local:DataGridTextSearch.IsTextMatch">
<Setter.Value>
<MultiBinding Converter="{StaticResource SearchValueConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" />
<Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" />
</MultiBinding>
</Setter.Value>
</Setter>
然后我们可以使用单元
附 IsTextMatch
属性使用设置高亮显示触发
Then we can use the Cells
attached IsTextMatch
property to set a highlight using a Trigger
<Style.Triggers>
<Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="Background" Value="Orange" />
</Trigger>
</Style.Triggers>
下面是一个工作示例显示我的rambilings:)
code:
namespace WpfApplication17
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
for (int i = 0; i < 20; i++)
{
TestData.Add(new TestClass { MyProperty = GetRandomText(), MyProperty2 = GetRandomText(), MyProperty3 = GetRandomText() });
}
}
private string GetRandomText()
{
return System.IO.Path.GetFileNameWithoutExtension(System.IO.Path.GetRandomFileName());
}
private ObservableCollection<TestClass> _testData = new ObservableCollection<TestClass>();
public ObservableCollection<TestClass> TestData
{
get { return _testData; }
set { _testData = value; }
}
}
public class TestClass
{
public string MyProperty { get; set; }
public string MyProperty2 { get; set; }
public string MyProperty3 { get; set; }
}
public static class DataGridTextSearch
{
// Using a DependencyProperty as the backing store for SearchValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SearchValueProperty =
DependencyProperty.RegisterAttached("SearchValue", typeof(string), typeof(DataGridTextSearch),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.Inherits));
public static string GetSearchValue(DependencyObject obj)
{
return (string)obj.GetValue(SearchValueProperty);
}
public static void SetSearchValue(DependencyObject obj, string value)
{
obj.SetValue(SearchValueProperty, value);
}
// Using a DependencyProperty as the backing store for IsTextMatch. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsTextMatchProperty =
DependencyProperty.RegisterAttached("IsTextMatch", typeof(bool), typeof(DataGridTextSearch), new UIPropertyMetadata(false));
public static bool GetIsTextMatch(DependencyObject obj)
{
return (bool)obj.GetValue(IsTextMatchProperty);
}
public static void SetIsTextMatch(DependencyObject obj, bool value)
{
obj.SetValue(IsTextMatchProperty, value);
}
}
public class SearchValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string cellText = values[0] == null ? string.Empty : values[0].ToString();
string searchText = values[1] as string;
if (!string.IsNullOrEmpty(searchText) && !string.IsNullOrEmpty(cellText))
{
return cellText.ToLower().StartsWith(searchText.ToLower());
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
}
XAML中:
<Window x:Class="WpfApplication17.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication17"
Title="MainWindow" Height="350" Width="525" Name="UI">
<StackPanel DataContext="{Binding ElementName=UI}">
<TextBox Name="SearchBox" />
<DataGrid x:Name="grid" local:DataGridTextSearch.SearchValue="{Binding ElementName=SearchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding TestData}" >
<DataGrid.Resources>
<local:SearchValueConverter x:Key="SearchValueConverter" />
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="local:DataGridTextSearch.IsTextMatch">
<Setter.Value>
<MultiBinding Converter="{StaticResource SearchValueConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" />
<Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" />
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="Background" Value="Orange" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
</DataGrid>
</StackPanel>
</Window>
结果:
如果你只是想选择基于单个列,您可以修改此行很容易。)
If you just want to select the row based on a single Column you can modify quite easily :).
覆盖的风格 DataGridRow
而不是 DataGridCell
。
<Style TargetType="{x:Type DataGridRow}">
第一遍你想要到该属性的 IMultiValueConverter
这应该是你的的DataContext
<MultiBinding Converter="{StaticResource SearchValueConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="DataContext.MyProperty" />
<Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" />
</MultiBinding>
然后修改触发
设置 IsSelected
在行
<Style.Triggers>
<Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
应该是这样的:
<DataGrid x:Name="grid" local:DataGridTextSearch.SearchValue="{Binding ElementName=SearchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding TestData}" >
<DataGrid.Resources>
<local:SearchValueConverter x:Key="SearchValueConverter" />
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="local:DataGridTextSearch.IsTextMatch">
<Setter.Value>
<MultiBinding Converter="{StaticResource SearchValueConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="DataContext.MyProperty" />
<Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" />
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
</DataGrid>
结果:
这篇关于从文本框使用MVVM正确的DataGrid搜索在WPF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!