【问题标题】:Select a row in dataGrid by searching for a string programatically通过以编程方式搜索字符串来选择 dataGrid 中的一行
【发布时间】:2013-05-22 10:14:12
【问题描述】:

我有一个名为“txtSearch”的文本框

我还有一个以编程方式填充的 DataGrid。

现在我想在 DataGridView 中搜索 txtSearch.text 并基于此选择整行。

我希望它以编程方式完成。我的意思是不使用 XAML。

有可能吗?

【问题讨论】:

  • 如果不想使用 XAML,为什么要在 WPF 中实现?改为使用 Windows 窗体。
  • 我在winforms中创建了一个应用程序。为了简单和良好的动画,我将我的项目翻译成 WPF。
  • 如果你翻译成 WPF,最好花点时间学习数据绑定,因为它会给你在 WPF 世界中带来巨大的好处。
  • 100% 同意@tigran,WPF 不是关于“好的动画”。这是关于能够实际开发一些有用的东西。发布相关代码和 XAML,可能还有您需要的屏幕截图。

标签: c# wpf vb.net search datagrid


【解决方案1】:

首先,如果你在 WPF 中做某事,你最好这样做the WPF Way

如果您对学习 XAML 和 MVVM 不感兴趣,那么您宁愿回到恐龙无用的技术。

<Window x:Class="MiscSamples.DataGridSearch"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataGridSearch" Height="300" Width="300">
    <DockPanel>
        <DockPanel DockPanel.Dock="Top">
            <TextBlock Text="Search:" DockPanel.Dock="Left"/>
            <TextBox Text="{Binding SearchString, UpdateSourceTrigger=PropertyChanged}"/>
        </DockPanel>

        <DataGrid ItemsSource="{Binding ItemsView}" AutoGenerateColumns="True"/>
    </DockPanel>
</Window>

代码背后:

public partial class DataGridSearch : Window
{
    public DataGridSearch()
    {
        InitializeComponent();

        DataContext = new DataGridSearchViewModel();
    }
}

视图模型:

public class DataGridSearchViewModel: PropertyChangedBase
{
    private string _searchString;
    public string SearchString
    {
        get { return _searchString; }
        set
        {
            _searchString = value;
            OnPropertyChanged("SearchString");
            ItemsView.Refresh();
        }
    }

    private ICollectionView _itemsView;
    public ICollectionView ItemsView
    {
        get { return _itemsView; }
    }

    private ObservableCollection<DataGridSearchModel> _items;
    public ObservableCollection<DataGridSearchModel> Items
    {
        get { return _items ?? (_items = new ObservableCollection<DataGridSearchModel>()); }
    }

    public DataGridSearchViewModel()
    {
        _itemsView = CollectionViewSource.GetDefaultView(Items);
        _itemsView.Filter = x => Filter(x as DataGridSearchModel);

        Enumerable.Range(0, 100)
                  .Select(x => CreateRandomItem())
                  .ToList()
                  .ForEach(Items.Add);
    }

    private bool Filter(DataGridSearchModel model)
    {
        var searchstring = (SearchString ?? string.Empty).ToLower();

        return model != null &&
             ((model.LastName ?? string.Empty).ToLower().Contains(searchstring) ||
              (model.FirstName ?? string.Empty).ToLower().Contains(searchstring) ||
              (model.Address ?? string.Empty).ToLower().Contains(searchstring));
    }

    private DataGridSearchModel CreateRandomItem()
    {
        return new DataGridSearchModel
                   {
                       LastName = RandomGenerator.GetNext(1),
                       FirstName = RandomGenerator.GetNext(1),
                       Address = RandomGenerator.GetNext(4)
                   };
    }
}

数据项:

public class DataGridSearchModel:PropertyChangedBase
{
    public string LastName { get; set; }

    public string FirstName { get; set; }

    public string Address { get; set; }
}

PropertyChangedBase(MVVM 辅助类):

public class PropertyChangedBase:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        Application.Current.Dispatcher.BeginInvoke((Action) (() =>
                                                                 {
                                                                     PropertyChangedEventHandler handler = PropertyChanged;
                                                                     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
                                                                 }));
    }
}

随机生成器(仅用于生成随机字符串)

public static class RandomGenerator
{
    private static string TestData = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum";
    private static List<string> words;
    private static int maxword;
    private static Random random = new Random();

    static RandomGenerator()
    {
        words = TestData.Split(' ').ToList();
        maxword = words.Count - 1;
    }

    public static string GetNext(int wordcount)
    {
        return string.Join(" ", Enumerable.Range(0, wordcount)
                                          .Select(x => words[random.Next(0, maxword)]));
    }

    public static int GetNextInt(int min, int max)
    {
        return random.Next(min, max);
    }
}

结果:

  • 完全 MVVM。
  • 没有一行代码可以操作任何 UI 元素。这是 WPF 方式。
  • TextBox 绑定中的 UpdateSourceTrigger=PropertyChanged 使其在您键入时进行搜索。
  • 完全强类型的对象模型比使用DataTables 和类似的东西要好得多。
  • WPF 摇滚。只需将我的代码复制并粘贴到 File -&gt; New Project -&gt; WPF Application 中,然后自己查看结果即可。
  • 忘掉 winforms 的心态吧,它无关紧要、笨拙,会生成糟糕的代码,只会让人觉得菜鸟和不成熟。

【讨论】:

  • 感谢您的回答。我是一个VB的人。因此,我将首先转换您的代码并尝试实现它。尝试后我会在这里。
  • @Vishal 如果您愿意,可以安装一个Visual Studio Extension 来执行 VB.Net 和 C# 之间的转换。
  • 这里出现错误 (_items = new ObservableCollection());错误是 Operator = is not defined for System.Collections.ObjectModel.ObsevableCollection(Of MyProject.DataGridSearchModal) 和 System.Collections.ObjectModel.ObsevableCollection(Of MyProject.DataGridSearchModal)
  • @Vishal 在 VB.Net 中应该是 (_items = new ObservableCollection(of DataGridSearchModel))
  • @Vishal 您需要在 VB.Net 中将 C# ?? 运算符更改为 If()。看this
【解决方案2】:

你可能想使用像 ff 一样的数据绑定。代码如下

Dim m_Dt As New DataTable
Dim m_Bs As New BindingSource

Private Sub createDatatable()
    m_Dt.Columns.Clear()
    m_Dt.Columns.Add("FieldKey", GetType(System.Int16))
    m_Dt.Columns.Add("Field1", GetType(System.String))
    m_Dt.Columns.Add("Field2", GetType(System.String))
End Sub

Private Sub PopulateDatatable()
    For i As Integer = 0 To 10
        Dim dr As DataRow = m_Dt.NewRow
        dr("FieldKey") = i
        dr("Field1") = String.Format("field1Value-{0}", i)
        dr("field2") = String.Format("Field2Value-{0}", i)
        dr = m_Dt.Rows.Add
    Next

End Sub

Private Sub BindDatatableToDataGridView()
    m_Bs.DataSource = m_Dt
    m_DataGridview.DataSource = m_Bs
End Sub

Private Sub FindTextAndFocusOnRow()
    m_Bs.Position = m_Bs.Find("FieldKey", m_TxtSearchText.Text)
End Sub


Private Sub ModifyRowValues()
    m_Dt.Rows(m_Bs.Position)("Field1") = "FieldModified"
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多