强制对';s绑定到InkCanvas

本文关键字:绑定 InkCanvas | 更新日期: 2023-09-27 18:26:16

我有以下XAML:

<Image Visibility="Visible" 
       Source="{Binding ElementName=inkCanvas, 
                        Converter={StaticResource InkCanvasToImageSource}, 
                        UpdateSourceTrigger=PropertyChanged}">
</Image>
<InkCanvas x:Name="inkCanvas" />

我想做的是将InkCanvas笔划集合转换为BitmapImage。我正在使用MVVM,并希望在命令上执行此操作。我遇到的问题是,上面的代码不会触发转换器启动。我使用的是UWP,所以我只能将其中一个控件作为命令参数传递。

我需要一个方法来从一个转换到另一个,但我想在ViewModel中完成。

强制对';s绑定到InkCanvas

InkCanvas控件与InkPresenter对象的实例相关联(通过InkPresenter属性公开)。InkPresenter提供用于管理InkCanvas控件的墨迹数据的输入、处理和呈现的属性、方法和事件。因此,绑定到InkCanvas不会触发转换器启动,因为墨水输入完全由InkPresenter管理。并且InkCanvas.InkPresenter属性不是依赖属性,我们不能绑定到这个属性。因此,我们不能强制Image更新为InkCanvas。我们必须在代码背后进行,这可能会破坏MVVM的设计。

要更新Image,我们可以使用StrokesCollectedStrokesErased事件来检测墨水输入,并在这些事件中将所有InkStroke对象保存到BitmapImage。例如:

在XAML 中

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Image x:Name="MyImage" />
    <Border Grid.Row="1" BorderBrush="Red" BorderThickness="2">
        <InkCanvas x:Name="inkCanvas" />
    </Border>
</Grid>

在后面的代码中:

public MainPage()
{
    this.InitializeComponent();
    ...
    inkCanvas.InkPresenter.StrokesCollected += InkPresenter_StrokesCollected;
    inkCanvas.InkPresenter.StrokesErased += InkPresenter_StrokesErased;
}
private async void InkPresenter_StrokesErased(InkPresenter sender, InkStrokesErasedEventArgs args)
{
    var image = await SaveAsync();
    MyImage.Source = image;
}
private async void InkPresenter_StrokesCollected(InkPresenter sender, InkStrokesCollectedEventArgs args)
{
    var image = await SaveAsync();
    MyImage.Source = image;
}
private async Task<BitmapImage> SaveAsync()
{
    var bitmap = new BitmapImage();
    if (inkCanvas.InkPresenter.StrokeContainer.GetStrokes().Count > 0)
    {
        try
        {
            using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
            {
                await inkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream);
                stream.Seek(0);
                bitmap.SetSource(stream);
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex);
        }
    }
    return bitmap;
}

在这里,我只将图像设置为MyImage,您也可以将其设置为ViewModel,并在Image中使用Binding