【问题标题】:Copy/Paste on TreeView with Caliburn.Micro使用 Caliburn.Micro 在 TreeView 上复制/粘贴
【发布时间】:2013-11-29 14:54:50
【问题描述】:

我正在尝试使用 Caliburn.Micro 在 WPF TreeView 上实现复制和粘贴,但我一开始就卡住了。问题是我不知道在调用事件时复制或粘贴 TreeView 上的当前项目。下面是 TreeView 和事件处理程序的 xaml。有什么建议吗?

    <TreeView Name="Nodes" AllowDrop="True">
        <TreeView.ContextMenu>
            <ContextMenu ItemsSource="{Binding MenuItems}">
                <MenuItem Header="Copy" cal:Message.Attach="[Event Click] = [Action Copy($source, $eventArgs)]"></MenuItem>
                <MenuItem Header="Cut" cal:Message.Attach="[Event Click] = [Action Cut]"></MenuItem>
                <MenuItem Header="Paste" cal:Message.Attach="[Event Click] = [Action Paste($this)]" IsEnabled="{Binding IsPasteEnabled}"></MenuItem>
                <ContextMenu.ItemContainerStyle>
                    <Style TargetType="MenuItem">
                        <Setter Property="Header" Value="{Binding Name}"/>
                        <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
                        <Setter Property="Command" Value="{Binding MenuCommand}"/>
                    </Style>
                </ContextMenu.ItemContainerStyle>
            </ContextMenu>
        </TreeView.ContextMenu>
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeView.Resources>
            <HierarchicalDataTemplate ItemsSource="{Binding Childs}" DataType="{x:Type viewmodels:TreeListViewModel+Node}">
                <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
        </TreeView.Resources>
    </TreeView>

public void Copy(object sender, RoutedEventArgs args)
{
    // to do...
}

编辑: 来源:http://dfiles.eu/files/bsm545ti3

【问题讨论】:

    标签: c# wpf xaml treeview caliburn.micro


    【解决方案1】:

    这可能没有用,但我使用cal:Action.TargetWithoutContext 属性做了类似的事情,将DataContext 解析为特定的ViewModel。在我的例子中,我有几种不同类型的 ViewModel 都继承自一个基本的 TreeViewItemViewModel 类,但这不应该是你真正需要在这里考虑的事情。

    基本上,我将ContextMenuDataContext 设置为当前TreeView 节点所代表的实际ViewModel,允许我调用我在ViewModel 上定义的操作。

    在您的情况下,您可能不希望在 ViewModel 上定义通用复制/粘贴,但您可以触发 Copy/Cut/Paste 事件(使用 Caliburn.Micro EventAggregator),来自每个ViewModels,在事件信息中传递自己。

    重要的一点:

    <ContextMenu cal:Action.TargetWithoutContext="{Binding DataContext, RelativeSource={RelativeSource Self}}">
    

    我根据节点表示的内容定义了不同的ContextMenu,因此它位于HierarchicalDataTemplate 中。它看起来像这样(我使用StackPanel 来显示多个对象,如果单击StackPanel 本身,则允许出现ContextMenu

    <HierarchicalDataTemplate ItemsSource="{Binding Childs}"
                              DataType="{x:Type viewmodels:TreeListViewModel+Node}">
        <StackPanel Orientation="Horizontal">
            <StackPanel.ContextMenu>
                <ContextMenu cal:Action.TargetWithoutContext="{Binding DataContext, RelativeSource={RelativeSource Self}}">
                    <MenuItem Header="Cut" cal:Message.Attach="Cut" />
                    <MenuItem Header="Copy" cal:Message.Attach="Copy" />
                    <MenuItem Header="Paste" cal:Message.Attach="Paste" />
                </ContextMenu>
            </StackPanel.ContextMenu>
            <TextBlock Text="{Binding Name}" />
        </StackPanel>
    </HierarchicalDataTemplate>
    

    可能有更简单/直接的方法。

    也值得搜索Caliburn.Micro讨论,例如:http://caliburnmicro.codeplex.com/discussions/256163

    【讨论】:

    • 嗨,我认为你的解决方案对我有帮助 :) 但我也上传了我的项目,所以如果你可以查看它并告诉我如何设置“粘贴”按钮启用,具体取决于是否复制了某些节点/切。
    • 您好,我回家后会试试看。我可能会尝试在托管此TreeView 控件的ViewModel 上的NodeClipBoard 属性中跟踪复制/剪切项目,然后您可以在Copy/Cutting 时填充该属性,并在Pasting 时使用它。您可以将Paste 命令绑定到CanPaste 属性(将启用/禁用该选项的CM 约定),该属性检查NodeClipBoard 项是否为非空。您可能需要制作一个额外的标志来管理Cut(因此ClipBoard 在粘贴后被清除。可能有更清洁的方法=D
    • 我已经修改了我的项目,但我有一个“错误”。当我复制一些子节点并在另一个上按粘贴时。这个节点有可用的粘贴命令,它不应该因为剪贴板每次都被清除。
    • 听起来您可能需要调用 NotifyPropertyChanged(() =&gt; CanPaste) 之类的东西来让 UI 知道 CanPaste 属性在您粘贴后可能已刷新。可能还值得研究一下您是如何实现复制/粘贴的(决定您是要在现有节点上实际创建ViewModel 的克隆,还是移动现有实例(对于剪切)。
    • 这就是我解决它的方法。每次用户右键单击该节点时,它都会被选中,我也会调用 node.NotifyOfPropertyChange("CanPaste");
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多