MVVM 绑定到 InkCanvas

发布于 2024-07-16 08:26:31 字数 615 浏览 5 评论 0原文

我似乎遇到了障碍。 我们将 MVVM 与 Prism 结合使用,并且有一个需要 Ink Canvas 的视图。 我创建了一个从 ViewModel 绑定到 View 的 StrokeCollection。 我可以从视图模型设置集合,但在用户绘制时视图模型不会发生更改。 有办法让这项工作发挥作用吗?

我的 ViewModel 中的属性如下:

private StrokeCollection _strokes;
public StrokeCollection Signature
{
     get
     {
         return _strokes;
     }
     set
     {
         _strokes = value;
         OnPropertyChanged("Signature");
     }
}

这是我的 XAML 绑定行:

<InkCanvas x:Name="MyCanvas" Strokes="{Binding Signature, Mode=TwoWay}" />

由于某种原因,显然 InkCanvas 永远不会通知 ViewModel 任何更改。

I seem to have ran into a road block. We are using MVVM with Prism and have a View that requires an Ink Canvas. I've create a StrokeCollection that is being bound from my ViewModel to the View. I am able to set the collection from my viewmodel but changes are not coming up to the ViewModel while the user draws. Is there a way to make this work?

My Property in my ViewModel is as follows:

private StrokeCollection _strokes;
public StrokeCollection Signature
{
     get
     {
         return _strokes;
     }
     set
     {
         _strokes = value;
         OnPropertyChanged("Signature");
     }
}

Here is my XAML binding line:

<InkCanvas x:Name="MyCanvas" Strokes="{Binding Signature, Mode=TwoWay}" />

For some reason apparently the InkCanvas never notifies the ViewModel of any change.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苄①跕圉湢 2024-07-23 08:26:31

您的方法的问题在于您假设 InkCanvas 创建 StrokeCollection。 它没有 - 它只是添加和删除其中的项目。 如果该集合不可用(即 null),则绑定将失败,并且 InkCanvas 不会对其执行任何操作 。 因此:

  1. 您需要创建一个 StrokeCollection
  2. 您需要假设集合的内容会发生变化,而不是集合本身

示例代码:

public class ViewModel : INotifyPropertyChanged
{
    private readonly StrokeCollection _strokes;

    public ViewModel()
    {
        _strokes = new StrokeCollection();
        (_strokes as INotifyCollectionChanged).CollectionChanged += delegate
        {
            //the strokes have changed
        };
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public StrokeCollection Signature
    {
        get
        {
            return _strokes;
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

和 XAML:

<InkCanvas Strokes="{Binding Signature}"/>

The problem with your approach is that you assume the InkCanvas creates the StrokeCollection. It does not - it merely adds and removes items from it. And if the collection isn't available (ie. is null), the binding will fail and the InkCanvas won't do anything with it. So:

  1. You need to create a single StrokeCollection
  2. You need to assume the contents of the collection will change, not the collection itself

Example code:

public class ViewModel : INotifyPropertyChanged
{
    private readonly StrokeCollection _strokes;

    public ViewModel()
    {
        _strokes = new StrokeCollection();
        (_strokes as INotifyCollectionChanged).CollectionChanged += delegate
        {
            //the strokes have changed
        };
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public StrokeCollection Signature
    {
        get
        {
            return _strokes;
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

And XAML:

<InkCanvas Strokes="{Binding Signature}"/>
默嘫て 2024-07-23 08:26:31

StrokeCollection 类有一个名为“StrokesChanged”的事件,当您在视图中绘制某些内容时,该事件总是会被触发。 该事件包含更新的笔画集合。

XAML:

<Grid>
    <InkCanvas Strokes="{Binding Signature}"/>
</Grid>

VM:

public class TestViewModel : INotifyPropertyChanged
{
    public StrokeCollection Signature { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public TestViewModel()
    {
        Signature = new StrokeCollection();
        Signature.StrokesChanged += Signature_StrokesChanged;
    }

    void Signature_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
    {
        //PUT A BREAKPOINT HERE AND CHECK
        Signature = (System.Windows.Ink.StrokeCollection)sender;
    }

}

希望有帮助!

StrokeCollection class have an event called "StrokesChanged" that is always fired when you draw something in the View. That event contains the collection of strokes updated.

XAML:

<Grid>
    <InkCanvas Strokes="{Binding Signature}"/>
</Grid>

VM:

public class TestViewModel : INotifyPropertyChanged
{
    public StrokeCollection Signature { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public TestViewModel()
    {
        Signature = new StrokeCollection();
        Signature.StrokesChanged += Signature_StrokesChanged;
    }

    void Signature_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
    {
        //PUT A BREAKPOINT HERE AND CHECK
        Signature = (System.Windows.Ink.StrokeCollection)sender;
    }

}

Hope it helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文