【问题标题】:undo/redo command stack for InkCanvasInkCanvas 的撤消/重做命令堆栈
【发布时间】:2023-03-10 22:18:01
【问题描述】:

我正在使用 InkCanvas 创建类似绘画的应用程序,我愿意实现 Undo 和我的应用程序中的重做功能。

为 InkCanvas 实施撤消/重做的最佳方法是什么??

【问题讨论】:

    标签: wpf silverlight-4.0 wpf-controls


    【解决方案1】:

    我已经为 WPF 应用程序实现了撤消/重做,并最终将我的撤消/重做代码发布到 http://muf.codeplex.com/。您也可以通过 NuGet 获取它。只需寻找“MUF”或“Monitored Undo Framework”。它包括对 Silverlight 4.0 以及 .NET 3.5、4.0 和 WP7 的支持。

    在我的 WPF 应用程序中,我们还有一个支持撤消/重做的 InkCanvas。在我的例子中,InkCanvas 的笔画与其余数据一起保存到数据库中。我在 InkCanvas 上连接了各种事件,以检测笔画何时发生变化。然后使用这些事件来更新实体。

    实体跟踪笔画的变化并集成到撤消/重做库中。当用户单击撤消时,库会将实体更改回其原始状态。然后我会将这些笔画推回 InkCanvas 并触发布局更新。

    欢迎在 codeplex 网站 (http://muf.codeplex.com/) 上发表评论和提问。您还可以在那里找到完整的文档和示例应用程序。

    【讨论】:

    • 图书馆很棒!如果你能提供它在 inkcanvas 中的用法,那就太好了。例如:var undoRoot = UndoService.Current[this.inkCanvas]
    • 见鬼,MUF 很难用。我无法让简单的撤消/重做代码正常工作。 codeplex 需要更多示例,而且不像照片应用程序或单元测试那样复杂。您应该为用户提供最简单的示例以使 MUF 正常工作。
    • @VasiliyBorovyak 我很乐意为您提供帮助。随时在 codeplex 网站上发布问题,我将在那里继续讨论。
    【解决方案2】:

    我知道为时已晚,但如果有人在这里使用 InkCanvas,那么this answer 可能会有所帮助:

    public partial class MainWindow : Window
    {
        System.Windows.Ink.StrokeCollection _added;
        System.Windows.Ink.StrokeCollection _removed;
        private bool handle = true;
        public MainWindow()
        {
            InitializeComponent();
            inkCanvas1.Strokes.StrokesChanged += Strokes_StrokesChanged;
        }
    
        private void Strokes_StrokesChanged(object sender, System.Windows.Ink.StrokeCollectionChangedEventArgs e)
        {
            if(handle)
            {
                _added = e.Added;
                _removed = e.Removed;
            }
        }
    
    
        private void Undo(object sender, RoutedEventArgs e)
        {
            handle = false;
            inkCanvas1.Strokes.Remove(_added);
            inkCanvas1.Strokes.Add(_removed);
            handle = true;
        }
    
        private void Redo(object sender, RoutedEventArgs e)
        {
            handle = false;
            inkCanvas1.Strokes.Add(_added);
            inkCanvas1.Strokes.Remove(_removed);
            handle = true;
        }
    }
    

    在 XAML 中:

    <InkCanvas x:Name="inkCanvas1" Width="100" Height="100" Background="Yellow"/>
    <Button Content="Undo" Click="Undo" />
    <Button Content="Redo" Click="Redo"/>
    

    【讨论】:

      【解决方案3】:

      我不知道这是否有帮助。但UNDO的一种非常简单的方法是:

      YourWindow.xaml.cs

       private void Undo_Click(object sender, RoutedEventArgs e)
              {
                  if (YourInkCanva.Strokes.Count > 0)
                  {
                      YourInkCanva.Strokes.RemoveAt(YourInkCanva.Strokes.Count - 1);
                  }
                  else
                  {
                      // Else Do Nothing.
                  }
              }
      
      • 您可能希望将 YourInkCanva 替换为您的 inkcanva 名称。

      【讨论】:

        猜你喜欢
        • 2021-06-04
        • 2011-06-14
        • 1970-01-01
        • 2017-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-05
        相关资源
        最近更新 更多