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

时间:2014-06-01 15:29:57

标签: c# wpf checkbox datagrid

我有一个DataGrid,我用我的sql数据库填充数据。 现在我想从我选中的行中获取一个特定的单元格(第二个单元格)。

这就是我现在拥有的: 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#代码:

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

运行时出错:

  

System.ArgumentOutOfRangeException

     

{&#34;指数超出范围。必须是非负数且小于集合的大小。\ r \ n参数名称:index&#34;}

我做错了什么?我是否必须使用另一种方法来获取我想要的细胞?

6 个答案:

答案 0 :(得分:8)

我终于找到了!非常简单。

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

答案 1 :(得分:6)

MVVM模式。

您的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>

视图模型:

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

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

}

您的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:

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;
}

将xaml中的命令绑定到所选项目。这样它将成为CheckCommand的参数:

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

我希望这能涵盖一切。当然,您需要EventHandlers与App.xaml.cs进行通信,但我不知道您在处理单元格后想要做什么。我只做了3次,我希望它能解决。

答案 2 :(得分:3)

使用它100%正常工作。

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

答案 3 :(得分:0)

如果我理解正确,您希望从属性的选定行获取值,该值是绑定到DataGrid第二列的数据。但是,您向我们展示的代码执行此操作:

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

你的错误告诉你......

  

指数超出范围。必须是非负数且小于集合的大小。
  参数名称:index

...因为当您只选择了一个(或没有)项目时,您试图从SelectedItems集合中访问第二个项目。因此,您使用的索引(1)超出了范围。

但是,一旦你修正了这个错误,你就会立刻发现另一个错误,告诉你在DataGrid(你的row参数的类型)和你的任何类型之间没有默认的强制转换设置在DataGrid中,再次由于这一行:

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

这应该是......

YourDataType row = myGrid.SelectedItems[0];

...因为SelectedItems属性返回所选集合中的项目。从所选行获得数据项后,您需要做的就是从中访问所需的属性...我相信您是在ItemID属性值之后:

int ItemId = row.ItemID;

答案 4 :(得分:0)

在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);
    }

答案 5 :(得分:0)

YourDataGrid.SelectedIndex = X; 
DataRowView v = (DataRowView)YourDataGrid.SelectedItem;
TextBox1.Text = v[0].ToString();
TextBox2.Text = v[1].ToString();
TextBox3.Text = v[2].ToString();

例如,如果要在文本框中使用单元格值。