WPF Datagrid set selected row

后端 未结 8 1245
无人共我
无人共我 2020-11-27 05:08

How do I use the Datagrid.SelectedItem to select a row programmatically?

Do I first have to create a IEnumerable of DataGridRow

相关标签:
8条回答
  • 2020-11-27 05:27

    // In General to Access all rows //

    foreach (var item in dataGrid1.Items)
    {
        string str = ((DataRowView)dataGrid1.Items[1]).Row["ColumnName"].ToString();
    }
    

    //To Access Selected Rows //

    private void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        try
        {
            string str = ((DataRowView)dataGrid1.SelectedItem).Row["ColumnName"].ToString();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 05:28

    please check if code below would work for you; it iterates through cells of the datagris's first column and checks if cell content equals to the textbox.text value and selects the row.

    for (int i = 0; i < dataGrid.Items.Count; i++)
    {
        DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(i);
        TextBlock cellContent = dataGrid.Columns[0].GetCellContent(row) as TextBlock;
        if (cellContent != null && cellContent.Text.Equals(textBox1.Text))
        {
            object item = dataGrid.Items[i];
            dataGrid.SelectedItem = item;
            dataGrid.ScrollIntoView(item);
            row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
            break;
        }
    }
    

    hope this helps, regards

    0 讨论(0)
  • 2020-11-27 05:32

    I came across this fairly recent (compared to the age of the question) TechNet article that includes some of the best techniques I could find on the topic:

    WPF: Programmatically Selecting and Focusing a Row or Cell in a DataGrid

    It includes details that should cover most requirements. It is important to remember that if you specify custom templates for the DataGridRow for some rows that these won't have DataGridCells inside and then the normal selection mechanisms of the grid doesn't work.

    You'll need to be more specific on what datasource you've given the grid to answer the first part of your question, as the others have stated.

    0 讨论(0)
  • 2020-11-27 05:35

    I've searched solution to similar problem and maybe my way will help You and anybody who face with it.

    I used SelectedValuePath="id" in XAML DataGrid definition, and programaticaly only thing I have to do is set DataGrid.SelectedValue to desired value.

    I know this solution has pros and cons, but in specific case is fast and easy.

    Best regards

    Marcin

    0 讨论(0)
  • 2020-11-27 05:40

    I have changed the code of serge_gubenko and it works better

    for (int i = 0; i < dataGrid.Items.Count; i++)
    {
        string txt = searchTxt.Text;
        dataGrid.ScrollIntoView(dataGrid.Items[i]);
        DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(i);
        TextBlock cellContent = dataGrid.Columns[1].GetCellContent(row) as TextBlock;
        if (cellContent != null && cellContent.Text.ToLower().Equals(txt.ToLower()))
        {
            object item = dataGrid.Items[i];
            dataGrid.SelectedItem = item;
            dataGrid.ScrollIntoView(item);
            row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
            break;
        }
    }
    
    0 讨论(0)
  • 2020-11-27 05:44

    It's a little trickier to do what you're trying to do than I'd prefer, but that's because you don't really directly bind a DataGrid to a DataTable.

    When you bind DataGrid.ItemsSource to a DataTable, you're really binding it to the default DataView, not to the table itself. This is why, for instance, you don't have to do anything to make a DataGrid sort rows when you click on a column header - that functionality's baked into DataView, and DataGrid knows how to access it (through the IBindingList interface).

    The DataView implements IEnumerable<DataRowView> (more or less), and the DataGrid fills its items by iterating over this. This means that when you've bound DataGrid.ItemsSource to a DataTable, its SelectedItem property will be a DataRowView, not a DataRow.

    If you know all this, it's pretty straightforward to build a wrapper class that lets you expose properties that you can bind to. There are three key properties:

    • Table, the DataTable,
    • Row, a two-way bindable property of type DataRowView, and
    • SearchText, a string property that, when it's set, will find the first matching DataRowView in the table's default view, set the Row property, and raise PropertyChanged.

    It looks like this:

    public class DataTableWrapper : INotifyPropertyChanged
    {
        private DataRowView _Row;
    
        private string _SearchText;
    
        public DataTableWrapper()
        {
            // using a parameterless constructor lets you create it directly in XAML
            DataTable t = new DataTable();
            t.Columns.Add("id", typeof (int));
            t.Columns.Add("text", typeof (string));
    
            // let's acquire some sample data
            t.Rows.Add(new object[] { 1, "Tower"});
            t.Rows.Add(new object[] { 2, "Luxor" });
            t.Rows.Add(new object[] { 3, "American" });
            t.Rows.Add(new object[] { 4, "Festival" });
            t.Rows.Add(new object[] { 5, "Worldwide" });
            t.Rows.Add(new object[] { 6, "Continental" });
            t.Rows.Add(new object[] { 7, "Imperial" });
    
            Table = t;
    
        }
    
        // you should have this defined as a code snippet if you work with WPF
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler h = PropertyChanged;
            if (h != null)
            {
                h(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        // SelectedItem gets bound to this two-way
        public DataRowView Row
        {
            get { return _Row; }
            set
            {
                if (_Row != value)
                {
                    _Row = value;
                    OnPropertyChanged("Row");
                }
            }
        }
    
        // the search TextBox is bound two-way to this
        public string SearchText
        {
            get { return _SearchText; }
            set
            {
                if (_SearchText != value)
                {
                    _SearchText = value;
                    Row = Table.DefaultView.OfType<DataRowView>()
                        .Where(x => x.Row.Field<string>("text").Contains(_SearchText))
                        .FirstOrDefault();
                }
            }
        }
    
        public DataTable Table { get; private set; }
    }
    

    And here's XAML that uses it:

    <Window x:Class="DataGridSelectionDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
            xmlns:DataGridSelectionDemo="clr-namespace:DataGridSelectionDemo" 
            Title="DataGrid selection demo" 
            Height="350" 
            Width="525">
        <Window.DataContext>
            <DataGridSelectionDemo:DataTableWrapper />
        </Window.DataContext>
        <DockPanel>
            <Grid DockPanel.Dock="Top">
            <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Label>Text</Label>
                <TextBox Grid.Column="1" 
                         Text="{Binding SearchText, Mode=TwoWay}" />
            </Grid>
            <dg:DataGrid DockPanel.Dock="Top"
                         ItemsSource="{Binding Table}"
                         SelectedItem="{Binding Row, Mode=TwoWay}" />
        </DockPanel>
    </Window>
    
    0 讨论(0)
提交回复
热议问题