在WPF C#中将ListView的项目复制到剪贴板

8

如何将绑定到数据库字段的WPF ListView中选择的项复制到剪贴板?

谢谢 Cristian

3个回答

6
我认为您需要监视SelectionChanged事件,然后以特定文本格式对项目进行格式化,最后利用Clipboard.SetText方法将项目设置到剪贴板中。

http://msdn.microsoft.com/en-us/library/system.windows.clipboard.aspx

private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
        foreach (var item in e.AddedItems.OfType<ListViewItem>())
        {
                Clipboard.SetText(item.ToString());
        }
}

这个答案看起来更加简洁。有了这个基本格式,你甚至可以直接获取底层数据和格式。 - Chris Ridenour

6

如果您希望获取显示的内容而不是类属性上的数据,则需要直接从控件中获取数据。

        var sb = new StringBuilder();
        foreach(var item in this.listview1.SelectedItems)
        {
            var lvi = this.listview1.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem;
            var cell = this.GetVisualChild<ContentPresenter>(lvi);
            var txt = cell.ContentTemplate.FindName("txtCodCli", cell) as TextBlock;
            sb.Append(txt.Text);
            //TODO: grab the other column's templated controls here & append text
        }
        System.Windows.Clipboard.SetData(DataFormats.Text, sb.ToString());

这假设你在XAML中有以下内容:
<TextBlock x:Name="txtCodCli" TextAlignment="Left" Text="{Binding Path=VFT_CLI_CODICE}" />

"

GetVisualChild T是什么意思

"
    public T GetVisualChild<T>(Visual parent) where T : Visual
    {
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        {
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v as T;
            if (child == null)
            {
                child = GetVisualChild<T>(v);
            }
            if (child != null)
            {
                break;
            }
        }
        return child;
    }

你好,这里有一段XAML代码,但是它似乎无法正常工作: <ListView.View> <GridView> <GridViewColumn Width="80"> <GridViewColumnHeader Content="Cod. Cli."></GridViewColumnHeader> <GridViewColumn.CellTemplate> <DataTemplate> <StackPanel> <TextBlock TextAlignment="Left" Text="{Binding Path=VFT_CLI_CODICE}" /> </StackPanel> - Cristian
foreach(var item in this.listview1.SelectedItems) { var lvi = this.listview1.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem; var myBoundItem = lvi.Content as MyClass; sb.AppendLine(myBoundItem.VFT_CLI_CODICE); } System.Windows.Clipboard.SetData(DataFormats.Text, sb.ToString());这里的"MyClass"是具有VFT_CLI_CODICE属性的任何对象。 - Software.Developer
这个程序目前可以正常工作,但我需要以编程方式获取ListView上可见的列,因为并非所有“MyClass”字段都会显示。对于某些字段,我正在应用一些转换器,并希望将数据复制到剪贴板中,并应用相应的格式! - Cristian
这将对虚拟化列表(即默认情况下)失败,因为容器不存在于大多数当前不在视图中的项目。 - Mark

1
我用以下方法解决了这个问题。我添加了Ctrl+C事件监听器,然后添加了将内容复制到剪贴板的逻辑。

XAML

<Window 
    ....
        Loaded="Window_Loaded"
        ...>

在代码中
private void WindowKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.C && Keyboard.Modifiers == ModifierKeys.Control)
            {
                var sb = new StringBuilder();
                var selectedItems = LVLog.SelectedItems;

                foreach(var item in selectedItems)
                {
                    sb.Append($"{item.ToString()}\n");
                }

                Clipboard.SetDataObject(sb.ToString());
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接