繁体   English   中英

如何将 wpf 数据网格粘贴到 observablecollection

[英]How do I paste in a wpf datagrid to an observablecollection

我有一个 WPF Datagrid,我通过它捕获粘贴命令

<CommandBinding Command="{x:Static ApplicationCommands.Paste}"
                            Executed="CommandBinding_Paste_Executed"/>

在“CommandBinding_Paste_Executed”中,我可以循环浏览所有选定的单元格并可以看到字段名称,我需要将剪贴板数据粘贴到我的可观察集合中。

不幸的是,我无法弄清楚如何引用该集合的成员。 我意识到下面是错误的,但它应该让你知道我正在尝试什么......

foreach (DataGridCellInfo cell in MyDataGrid.SelectedCells)
{
   string columnName = cell.Column.SortMemberPath;
   int rowIndex = ????;
   MyCollection[rowIndex].columnName ??? = Clipboard.GetText();
}

我错过了一些明显的东西吗? 或者我是从错误的角度尝试这个。

好的,所以它在谷歌搜索 wpf 数据网格粘贴后出现,我应该一直在寻找的是列映射。 仍然很难相信这些不是一个更简单的答案,但这就是我所得到的。 主窗口.xaml

<Grid>
    <DataGrid x:Name="DGrid" ItemsSource="{Binding Path=Stuff}"
              SelectedItem="{Binding DGSelection}"
              CellEditEnding="DGrid_CellEditEnding"
              SelectionUnit="Cell">
        <DataGrid.CommandBindings>
            <CommandBinding Command="{x:Static ApplicationCommands.Paste}" CanExecute="CanPaste" Executed="Paste"/>
        </DataGrid.CommandBindings>
        
        <DataGrid.Columns>
            <DataGridTextColumn Header="First name" Binding="{Binding FirstName}"/>
            <DataGridTextColumn Header="Surname" Binding="{Binding Surname}"/>
            <DataGridTextColumn Header="Country" Binding="{Binding Country}"/>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

个人.cs

public class Person : INotifyPropertyChanged
{
    public string FirstName { get; set; }
    public string Surname { get; set; }
    public string Country { get; set; }

    public Person()
    { }

    public Person(string firstName, string surname, string country)
    {
        FirstName = firstName;
        Surname = surname;
        Country = country;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

PeopleViewModel.cs

public class PeopleViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Person> people;
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// property map to store the column indexes and names
    /// eg: 0, FirstName
    /// </summary>
    private Dictionary<int, string> propertyMap;

    public PeopleViewModel()
    {
        people = new ObservableCollection<Person>();
        people.Add(new Person("Bruce", "Willis", "USA"));
        people.Add(new Person("Sarah", "Connor", "USA"));
        people.Add(new Person("Adolph", "Hitler", "Germany"));
        people.Add(new Person("Rowan", "Atkinson", "United Kingdom"));
        people.Add(new Person("Ryan", "Reynolds", "Canada"));

        propertyMap = new Dictionary<int, string>();
    }

    public ObservableCollection<Person> PeopleList
    {
        get => people;
        set
        {
            people = value;
            OnPropertyChanged("PeopleList");
        }
    }

    public void AddColumnMapping(int displayIndex, string propertyName)
    {
        propertyMap[displayIndex] = propertyName;
    }

    private void SetProperty(Person person, string propertyName, string cellItem)
    {
        PropertyInfo propertyInfo = person.GetType().GetProperty(propertyName);
        if (propertyInfo == null)
            throw new Exception($"Could not find property '{propertyName}'");

        if (propertyInfo.PropertyType != typeof(string))
            throw new Exception("Only coded for string values at this time");

        propertyInfo.SetValue(person, cellItem, null);
        person.OnPropertyChanged(propertyName);
    }

    public void Paste(int row, string column, string value)
    {
        Person person = PeopleList[row];
        SetProperty(person, column, value);
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

主窗口.xaml.cs

public partial class MainWindow : Window
{
    public PeopleViewModel people = new PeopleViewModel();
    public MainWindow()
    {
        InitializeComponent();
        DGrid.ItemsSource = people.PeopleList;
    }

    private void CanPaste(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = Clipboard.GetDataObject() != null;
    }

    private void Paste(object sender, ExecutedRoutedEventArgs e)
    {
        Person person;
        int row;
        string column;

        string clipboardValue = Clipboard.GetText();
        if (clipboardValue.Substring(clipboardValue.Length - 2) == "\r\n")
            clipboardValue = clipboardValue.Substring(0, clipboardValue.Length - 2);

        IList<DataGridCellInfo> cells = DGrid.SelectedCells;
        foreach (DataGridCellInfo cell in cells)
        {
            person = cell.Item as Person;
            row = people.PeopleList.IndexOf(person);
            column = cell.Column.SortMemberPath;
            people.Paste(row, column, clipboardValue);
        }
    }
}

感谢 Peter_Smithson 在https://www.codeproject.com/Articles/246306/Implementing-Copy-Paste-for-WPF-DataGrid-net-4

暂无
暂无

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

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