2016-11-12 6 views
0

Я использую XamlCropControl и пытаюсь связать его свойство ImageSource в моей модели viewmodel.Связывание XAMLCropControl ImageSource в свойство ImageSource в 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(); 
     } 
    } 

В моем XAML я следующее

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

Но изображение не показывается. Но если я использую путь, как в образце, таком как

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

Это работает. Я установил точку останова в CropControl.cs, и действительно, Writeablebitmap был передан в свойство dependency, но он не показан. Что мне не хватает?

ответ

0

Предположим, что вы сделали все, что прямо о связывании данных, то в соответствии с открытым источником XamlCropControl вы предоставили, из вашего кода, вы установили WriteableBitmap как Source в CropControl.

Вы можете обратиться к исходному коду CropControl, в его 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, так как ваш источник является WriteableBitmap, здесь он не сможет отобразить и вернуть значение null. Это первая возможная причина для вашей проблемы. Если вы настаиваете на использовании 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, то событие ImageOpened будет волшебным У меня не будет, я не уверен, что здесь происходит. Но вы используете WriteableBitmap, нет ImageOpend события WriteableBitmap, вам все равно нужно будет изменить этот код. Например, я сейчас меняется так:

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); 
    } 
} 

Теперь он работает, и вы можете обработать исключение самостоятельно.

Поскольку вы не упомянули, какой шаблон вы использовали для разработки приложений UWP, я здесь просто используя стандартный метод доставки демо в случае, если вы имеете что-то неправильно с привязкой данных:

MainPage XAML:

<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" /> 

MainPageViewModel:

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 просто так:

public class CommandHandler : ICommand 
{ 
    public event EventHandler CanExecuteChanged; 

    private Action _action; 

    public CommandHandler(Action action) 
    { 
     this._action = action; 
    } 

    public bool CanExecute(object parameter) 
    { 
     return true; 
    } 

    public void Execute(object parameter) 
    { 
     this._action(); 
    } 
} 
+0

Отлично. Я использую Template10, но я могу настроить, чтобы следовать вашим рекомендациям. – PutraKg