简体   繁体   中英

Cant set the property (UWP)

I have property, and i need to refresh View always when property is changed, but it doesnt work

 public WriteableBitmap OriginalBitmap = new WriteableBitmap(1280, 720);
private Image OriginalImage = new Image();
public Image Original
{
    get { return OriginalImage; }
    set
    {
        this.OriginalImage = value;
        base.RaisePropertyChanged();
    }
}

XAML

 <Image Grid.Row="1"
           Grid.Column="1" 
           x:Name="OriginalImg"
           Source="{Binding Original}"
           DataContext="{StaticResource MainViewModel}"/>

Im using MVVM libs for RaisePropertyChanged

And method

public async Task<bool> ApplyEffectAsync(StorageFile file)
{

        fileStream = await file.OpenAsync(FileAccessMode.Read);
        OriginalBitmap.SetSource(fileStream);
        Original.Source = OriginalBitmap;
}

Original always null

Why? And how to fix?

You need to pass in the name of the property into the RaisePropertyChanged function. It uses that name to tell the UI that if it's bound to a property with that name, go get the updated value.

Here is the Article on RaisePropertyChanged from MSDN

It should look something like this

public Image Original
{
    get { return OriginalImage; }
    set
    {
        this.OriginalImage = value;
        base.RaisePropertyChanged("Original");
    }
}

At first, change SetSource to SetSourceAsync

await OriginalBitmap.SetSourceAsync(fileStream);

At second, I guess you don't initialize your Original property from your Page.

If you use MVVM - initialize this property.

((this.DataContext as MyViewModel).Original = myImage;

where myImage it's

x:Name="myImage"

If you don't use MVVM, change the ImageSource directly:

myImage.Source = OriginalBitmap

At third, if you use MVVM, you can change the property type to

public BitmapImage Original
{
    get { return _original; }
    set
    {
        _original = value;
        base.RaisePropertyChanged();
    }
}

...

 Original = OriginalBitmap;

and in XAML use this:

<Image Source="{Binding Original}"
       ....

There are a few things needs to be corrected:

Firstly, it is recommended setting the MainViewModel instance as page's datacontext. Please don't set the ViewModel as Image control's DataContext and don't bind ViewModel as StaticResource . You can set it in XAML like below:

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

Or you can set it on code-behind:

MainPageViewModel ViewModel=new MainPageViewModel();
public MainPage()
{
    this.InitializeComponent();
    this.DataContext = ViewModel;
}

Secondly, Image.Source is of type ImageSource . To set this property requires an instance of BitmapImage or WriteableBitmap . So, Original object should be changed from Image to BitMapImage or WriteableBitmap . You can use the following codes to convert a StorageFile to WriteableBitmap :

IRandomAccessStream randomStream=await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
WriteableBitmap bitmap = new WriteableBitmap(500, 500);
bitmap.SetSource(randomStream);

Thirdly, like @Anthony Russel said. the MVVM lib might need to know the propertyName of your property.

Update : Your ViewModel class should be similar like this:

public class MainPageViewModel : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    public WriteableBitmap _original;
    public WriteableBitmap Original
    {
        get { return this._original; }
        set
        {
            this._original = value;
            RaisePropertyChanged("Original");
        }
    }

    public MainPageViewModel()
    { }
    public MainPageViewModel(WriteableBitmap original)
    {
        this.Original = original;
    }

    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

And Xaml:

<Page.DataContext>
   <vm:MainPageViewModel x:Name="ViewModel"/>
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel VerticalAlignment="Center">
        <Image Source="{Binding Original}"
               x:Name="OriginalImg"
               ></Image>
        <Button Name="myBtn" Click="myBtn_Click" >Click Me</Button>
    </StackPanel>
</Grid>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM