将XAMLCropControl ImageSource绑定到ViewModel中的ImageSource属性失败

时间:2016-11-12 04:52:31

标签: xaml binding uwp crop windows-10-universal

我正在使用XamlCropControl并尝试在我的viewmodel中绑定其 private ImageSource source; public ImageSource Source { get { return source; } set { SetProperty(ref source, value); } } 属性。

StorageFile

图像从用户的图库中选取 private async void setImageSource() { if (ImageStorageFile != null) { var imageProperties = await ImageStorageFile.Properties.GetImagePropertiesAsync(); WriteableBitmap wb = new WriteableBitmap((int)imageProperties.Width, (int)imageProperties.Height); IRandomAccessStream fileStream = await ImageStorageFile.OpenAsync(FileAccessMode.Read); wb.SetSource(fileStream); Source = wb; Show(); } }

  <xamlcrop:CropControl Grid.Row="1" x:Name="cropControl" ImageSource="{Binding Source}" DesiredAspectRatio="{Binding AspectRatio, Mode=TwoWay}" />

在我的XAML中,我有以下

 <xamlcrop:CropControl x:Name="Crop" ImageSource="ms-appx:///Assets/wrench.jpg" />

但图像没有显示。但是,如果我使用像样本中的路径,如

CropControl.cs

它有效。我在Writeablebitmap中设置了一个断点,确实{{1}}已传递给dependencyproperty,但它没有显示。我错过了什么?

1 个答案:

答案 0 :(得分:0)

假设您已经完成了有关数据绑定的所有事情,那么根据您提供的XamlCropControl的开源,您可以从代码中将WriteableBitmap设置为Source的{​​{1}}。

您可以在CropControlCropControl方法中引用Setup()的源代码,这些方法用于在此控件上呈现图像源,代码如下:

DoFullLayout()

正如您在此处所见,它使用public void Setup() { // Check for loaded and template succesfully applied if (!_isLoaded || !_isTemplateApplied) { return; } _image.Source = ImageSource; var bi = _image.Source as BitmapImage; if (bi != null) { ... } } private void DoFullLayout() { if (!_isTemplateApplied) { return; } var bi = _image.Source as BitmapImage; if (bi == null) { return; } ... } 将图像源强制转换为BitmapImage,因为您的源是as,此处它将无法转换并返回null。这是您遇到问题的第一个可能原因。如果您坚持使用WriteableBitmap,则需要修改这些代码才能将WriteableBitmap更改为BitmapImage

另一个可能的问题是WriteableBitmap方法:

Setup

如果您传递var bi = _image.Source as WriteableBitmap; if (bi != null) { bi.ImageOpened += (sender, e) => { DoFullLayout(); if (this.ImageOpened != null) { this.ImageOpened(this, e); } }; } 作为来源,当我使用BitmapImage生成此UriSource时,一切都会顺利进行。但是,当我使用BitmapImage将文件流设置为此SetSource时,BitmapImage事件会被我的身边神奇地 NOT 触发,我是不知道这里发生了什么。但是您使用ImageOpenedWriteableBitmap没有ImageOpend事件,您无论如何都需要修改此代码。例如,我现在正在改变它:

WriteableBitmap

现在它可以工作,你可以自己处理异常。

由于您没有提到您用于UWP应用程序开发的模板,我在这里只是使用标准方法来提供演示,以防数据绑定出现问题:

MainPage xaml:

var bi = _image.Source as WriteableBitmap;
if (bi != null)
{
    //bi.ImageOpened += (sender, e) =>
    //{
    //    DoFullLayout();
    //    if (this.ImageOpened != null)
    //    {
    //        this.ImageOpened(this, e);
    //    }
    //};
    try
    {
        DoFullLayout();
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.Message);
    }
}

MainPageViewModel:

<Page.DataContext>
    <local:MainPageViewModel x:Name="ViewModel" />
</Page.DataContext>

...
<Border Grid.Row="0" BorderBrush="Red" BorderThickness="1">
    <xamlcrop:CropControl x:Name="Crop" ImageSource="{Binding Source}" DesiredAspectRatio="1.0" />
</Border>
<Button Content="Pick Image" Command="{Binding SetImageSource}" Grid.Row="1" />

我的public class MainPageViewModel : INotifyPropertyChanged { public MainPageViewModel() { source = null; } public ICommand SetImageSource { get { return new CommandHandler(() => this.setImageSource()); } } public async void setImageSource() { StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/wrench.jpg")); if (file != null) { using (var stream = await file.OpenReadAsync()) { WriteableBitmap wb = new WriteableBitmap(960, 1200); wb.SetSource(stream); Source = wb; } } else { } } private ImageSource source; public ImageSource Source { get { return source; } set { if (value != source) { source = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged([CallerMemberName]string propertyName = "") { if (this.PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } 很简单:

CommandHandler