强制更新绑定到InkCanvas的控件

时间:2015-12-08 17:57:39

标签: c# xaml mvvm uwp

我有以下XAML:

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

<InkCanvas x:Name="inkCanvas" />

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

我需要一种方法从一种方法转换为另一种方法,但我想在ViewModel中进行。

1 个答案:

答案 0 :(得分:1)

#include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" #include "iostream" using namespace cv; double contrast_measure( const Mat&img ) { Mat dx, dy; Sobel( img, dx, CV_32F, 1, 0, 3 ); Sobel( img, dy, CV_32F, 0, 1, 3 ); magnitude( dx, dy, dx ); return sum(dx)[0]; } int main( int argc, char** argv ) { char* filename = argc >= 2 ? argv[1] : (char*)"lena.jpg"; Mat src = imread( filename ); if(src.data) { std::cout << "original image : " << contrast_measure( src ) / 1e3 << std::endl; for( int i =3; i < 80; i+=2 ) { Mat blurred; GaussianBlur( src, blurred, Size(i,i), 0); imshow( "blurred image", blurred ); waitKey(200); std::cout << "blurred image : " << contrast_measure( blurred ) / 1e3 << std::endl; } } return 0; } 控件与InkPresenter对象的实例相关联(通过InkPresenter属性公开)。 InkCanvas提供用于管理InkPresenter控件的墨迹数据的输入,处理和呈现的属性,方法和事件。因此,绑定到InkCanvas不会触发转换器触发,因为墨迹输入完全由InkCanvas管理。并且InkPresenter属性不是依赖属性,我们无法绑定到此属性。因此,我们无法强制将InkCanvas.InkPresenter更新与Image绑定。我们必须在代码隐藏中执行此操作,这可能会破坏MVVM设计。

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

在XAML中

BitmapImage

在代码隐藏中:

<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; } ,您也可以将其设置为ViewModel并在MyImage中使用Binding