Dar*_*ens 18 c# wpf search datagrid mvvm
我是MVVM模式的新手,对于何时使用Code Behind有点困惑.我现在有一个非常简单的表单,包括一个TextBox和一个DataGrid.我想要的是能够让DataGrid根据TextBox更改其选定的项目.
我在Code Behind中完成了这项工作,使用以下代码可以正常工作:
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 { }
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我只想突出显示Datagrid中以文本框中的文本开头的项目,并允许用户按下按钮来编辑所选项目.
在Code Behind文件中有这个逻辑是否可以?或者我需要通过某种绑定来做到这一点?如果我应该通过带有绑定的视图模型执行此操作,任何方向都将受到赞赏.谢谢.
sa_*_*213 40
如果您只想突出显示带有文本的单元格,TextBox您可以创建一个AttatchedProperty用于DataGrid接受您的搜索值TextBox并创建另一个AttatchedProperty用于Cell表示匹配,您可以使用该匹配来设置Cell样式中的属性.然后我们创建一个IMultiValueConverter来检查Cell匹配搜索的值Text.
这样它就可以在其他项目上重复使用,因为你只需要AttachedProperties和Converter
绑定AttachedProperty SearchValue到你的TextBox Text财产.
<DataGrid local:DataGridTextSearch.SearchValue="{Binding ElementName=SearchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}"
Run Code Online (Sandbox Code Playgroud)
然后创建一个Stylefor DataGridCell并创建一个Setter,如果单元格文本匹配,则AttachedProperty IsTextMatch使用IMultiValueConverter返回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>
Run Code Online (Sandbox Code Playgroud)
然后我们可以使用Cells附加IsTextMatch属性来设置突出显示Trigger
<Style.Triggers>
<Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="Background" Value="Orange" />
</Trigger>
</Style.Triggers>
Run Code Online (Sandbox Code Playgroud)
码:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
结果:

如果你只想根据单个列选择行,你可以很容易地修改:).
覆盖样式DataGridRow而不是DataGridCell.
<Style TargetType="{x:Type DataGridRow}">
Run Code Online (Sandbox Code Playgroud)
第一次通过你想要的属性IMultiValueConverter应该是你的DataContext
<MultiBinding Converter="{StaticResource SearchValueConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="DataContext.MyProperty" />
<Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" />
</MultiBinding>
Run Code Online (Sandbox Code Playgroud)
然后更改Trigger设置IsSelected为Row
<Style.Triggers>
<Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
Run Code Online (Sandbox Code Playgroud)
应该是这样的:
<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>
Run Code Online (Sandbox Code Playgroud)
结果:

| 归档时间: |
|
| 查看次数: |
25524 次 |
| 最近记录: |