简体   繁体   English

从DataGrid WPF C#中的选定行获取特定单元格的数据

[英]Get data of specific cell from selected row in DataGrid WPF C#

I have a DataGrid which I fill with data from my sql database. 我有一个DataGrid,我从我的SQL数据库填充数据。 Now I want to get a specific cell (2nd cell) from the row I selected with a checkbox. 现在我想从我选中的行中获取一个特定的单元格(第二个单元格)。

This is what I have now: WPF XAML: 这就是我现在拥有的:WPF XAML:

<DataGrid Name="myGrid">
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox Checked="CheckBox_Checked"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    <DataGridTextColumn Header="CustomerID" Width="Auto" Binding="{Binding CustomerID}"/>
    <DataGridTextColumn Header="ItemID" Width="Auto" Binding="{Binding ItemID}"/>
<DataGrid>

C# code: C#代码:

private void CheckBox_Checked(object sender, RoutedEventArgs e)
    {
        DataGrid row = (DataGrid)myGrid.SelectedItems[1];
        System.Windows.MessageBox.Show(row);
    }

I get a error when running: 运行时出错:

System.ArgumentOutOfRangeException System.ArgumentOutOfRangeException

{"Index was out of range. Must be non-negative and less than the size of the collection.\\r\\nParameter name: index"} {“索引超出范围。必须是非负数且小于集合的大小。\\ r \\ nParameter name:index”}

What am I doing wrong? 我究竟做错了什么? Do I have to use another approach to get the cell I want? 我是否必须使用另一种方法来获取我想要的细胞?

I finally found it! 我终于找到了! Very simple. 很简单。

DataRowView drv = (DataRowView)myGrid.SelectedItem; 
String result = (drv["CustomerID"]).ToString(); 
MessageBox.Show(result);

MVVM Pattern. MVVM模式。

Your XAML: 你的XAML:

<DataGrid Name="myGrid" Grid.Row="1"  SelectionMode="Single" AutoGenerateColumns="False" CanUserAddRows="True" ItemsSource="{Binding YourCollection}" IsReadOnly="True" Background="#FFB8C1CB">
<DataGrid.Columns>

        <DataGridTextColumn Header="ID" Binding="{Binding yourColumnItem}" />

    </DataGrid.Columns>
</DataGrid>

ViewModel: 视图模型:

public ObservableCollection<YourType> YourCollection { get; private set; }
public DelegateCommand checkCommand { get; private set; }


public YourViewModel(){
    checkCommand = new checkCommand(param => checkExecuted(param));
}

private void CheckExecuted(Object param)
{
        YourType item = param as YourType;

        YourCollection = new ObservableCollection<YourType>();
        YourCollection = model.ReadInvoices();  //you'll need a model class
        DoStuff(item.yourColumnItem);  //get the cell you want
}

App.xaml.cs App.xaml.cs

private YourViewModel _ViewModel;

public App()
{
   _ViewModel = new YourViewModel();
}

protected override void OnStartup(StartupEventArgs e)
{
        base.OnStartup(e);

        _MainWindow = new MainWindow();
        _MainWindow.DataContext = _ViewModel;
        _MainWindow.Show();
        //delete the startupuri row from App.xaml

}

Your DelegateCommand class: 您的DelegateCommand类:

using System;
using System.Windows.Input;

namespace yourSolution.ViewModel
{

public class DelegateCommand : ICommand
{
    private readonly Action<Object> _Execute; 
    private readonly Func<Object, Boolean> _CanExecute; 


    public DelegateCommand(Action<Object> execute) : this(null, execute) { }


    public DelegateCommand(Func<Object, Boolean> canExecute, Action<Object> execute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }

        _Execute = execute;
        _CanExecute = canExecute;
    }


    public event EventHandler CanExecuteChanged;


    public Boolean CanExecute(Object parameter)
    {
        return _CanExecute == null ? true : _CanExecute(parameter);
    }


    public void Execute(Object parameter)
    {
        _Execute(parameter);
    }


    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, EventArgs.Empty);
    }
}
}

DatabaseModel.cs: DatabaseModel.cs:

public ObservableCollection<YourType> ReadInvoices()
{
        Connect();  //write connection
        YourCollection.Clear();  //this is a private data part
        MySqlCommand cmd = new MySqlCommand(write your query);
        MySqlDataReader dr = cmd.ExecuteReader();

        YourCollection.Clear();
        YourType item = new YourType();

        while (dr.Read()){
          item.column = dr.GetInt32("columnName"); //or any other type
          YourCollection.Add(item);
        }

        dr.Close();
        Disconnect();

return YourCollection;
}

Bind your command in the xaml to the selected item. 将xaml中的命令绑定到所选项目。 This way it will become the parameter for CheckCommand: 这样它将成为CheckCommand的参数:

Command="{Binding CheckCommand}" CommandParameter="{Binding ElementName=myGrid, Path=SelectedItem}"

I hope this covers everything. 我希望这涵盖了一切。 Of course you'll need EventHandlers to communicate with App.xaml.cs but I don't know what you want to do after processing your cell. 当然,您需要EventHandlers与App.xaml.cs进行通信,但我不知道您在处理单元格后想要做什么。 I've only done this 3 times, I hope it works out. 我只做了3次,我希望它能解决。

Use this it 100% working. 使用它100%工作。

object item = dataGrid1.SelectedItem;
           string ID = (dataGrid1.SelectedCells[0].Column.GetCellContent(item) as TextBlock).Text;

If I understand you correctly, you want to get the value from the selected row of the property that is data bound to the second column of your DataGrid . 如果我理解正确,您希望从属性的选定行获取值,该值是绑定到DataGrid第二列的数据。 However, the code that you showed us does not do that: 但是,您向我们展示的代码会这样做:

private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
    DataGrid row = (DataGrid)myGrid.SelectedItems[1]; // <--- 2nd item, not 2nd column!
    System.Windows.MessageBox.Show(row);
}

Your error was telling you... 你的错误告诉你......

Index was out of range. 指数超出范围。 Must be non-negative and less than the size of the collection. 必须是非负数且小于集合的大小。
Parameter name: index 参数名称:index

... because you were trying to access the second item from the SelectedItems collection when there was only one (or no) item selected. ...因为当只选择了一个(或没有)项时,您试图从SelectedItems集合中访问第二个项目。 Therefore, your used index ( 1 ) was out of range. 因此,您使用的索引( 1 )超出范围。

However, once you fixed that error, you would have immediately found another telling you that there is no default cast set up between a DataGrid (the type of your row parameter) and whatever type you have in the DataGrid , again due to this line: 但是,一旦你修复了这个错误,你就会立刻发现另一个告诉你在DataGrid (你的row参数的类型)和你在DataGrid的类型之间没有默认的强制转换设置,这也是由于这一行:

DataGrid row = (DataGrid)myGrid.SelectedItems[1];

This should be... 这应该是......

YourDataType row = myGrid.SelectedItems[0];

... because the SelectedItems property returns the items from the collection that are selected. ...因为SelectedItems属性返回所选集合中的项目。 Once you have the data item from the selected row, then all you need to do is access the desired property from it... I believe that you were after the ItemID property value: 从所选行获得数据项后,您需要做的就是从中访问所需的属性...我相信您在ItemID属性值之后:

int ItemId = row.ItemID;

in wpf this one worked for me 在wpf这个为我工作

<DataGrid Name="dataGridShowStudents">
</DataGrid>

private void dataGridShowStudents_MouseDoubleClick(object sender, MouseButtonEventArgs e){
        DataRowView drv = (DataRowView)dataGridShowStudents.SelectedItem;
        string result = drv[0].ToString();
        MessageBox.Show(result);
    }
YourDataGrid.SelectedIndex = X; 
DataRowView v = (DataRowView)YourDataGrid.SelectedItem;
TextBox1.Text = v[0].ToString();
TextBox2.Text = v[1].ToString();
TextBox3.Text = v[2].ToString();

If you want to use the cell value in a textbox, for example. 例如,如果要在文本框中使用单元格值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM