none
MVVM - Updating Image control size changed in ViewModel

    Question

  • Hello,

    I have an Image control in my XAML and I am trying to "tell" my ViewModel the current SizeX/SizeY of the Image.

    My code does not seem to work...

    XAML:

    <Window x:Class="ImageSizeTest.Window1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:vm="clr-namespace:ImageSizeTest"
      Title="Window1" Width="500" Height="500">
      <Window.DataContext>
        <vm:MyViewModel/>
      </Window.DataContext>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="*" />
          <RowDefinition Height="20" />
        </Grid.RowDefinitions>
        <Image Source="TestImage.png" Width="{Binding ImageSizeX, Mode=OneWayToSource}" Height="{Binding ImageSizeY, Mode=OneWayToSource}"/>
        <TextBlock Grid.Row="1" Text="{Binding Position}" />
      </Grid>
    </Window>
    

    C#:

      public partial class Window1 : Window
      {
        public Window1()
        {
          InitializeComponent();
        }
      }
    
      public class MyViewModel : INotifyPropertyChanged
      {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private double _imageSizeX;
        private double _imageSizeY;
        private string _currentSize;
    
        public double ImageSizeX 
        {
          set
          {
            _imageSizeX = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Position"));
            PropertyChanged(this, new PropertyChangedEventArgs("ImageSizeX"));
          }
        }
    
        public double ImageSizeY
        {
          set
          {
            _imageSizeY = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Position"));
            PropertyChanged(this, new PropertyChangedEventArgs("ImageSizeY"));
          }
        }
    
        public string Position 
        {
          get
          {
            return _imageSizeX.ToString() + "," + _imageSizeY.ToString();
          }
        }

    Can anyone tell me how this can be done?

    Thanks!!!

    Thursday, April 29, 2010 11:22 AM

Answers

All replies

  • I think you'll need dependencyproperties rather than plain properties.
    Thursday, April 29, 2010 11:57 AM
  • Hi,

     

    I am implementing INotifyPropertyChanged, so I don't think that's the issue.

     

    Thursday, April 29, 2010 12:09 PM
  • You can use a converter and a multivalue binding:

    You window will look like:

     

    <Window x:Class="ImageTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:vm="clr-namespace:ImageTest">
      <Window.Resources>
        <vm:Converter x:Key="Converter" />
      </Window.Resources>
      <Window.DataContext>
        <vm:MyViewModel/>
      </Window.DataContext>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="*" />
          <RowDefinition Height="20" />
        </Grid.RowDefinitions>
        <Image Source="Gray188.png" x:Name="image"/>
        <TextBlock Grid.Row="1">
          <TextBlock.Text>
            <MultiBinding Converter="{StaticResource Converter}">
            <Binding ElementName="image" Path="ActualWidth"/>
             <Binding ElementName="image" Path="ActualHeight"/>
             </MultiBinding>
          </TextBlock.Text>
        </TextBlock>
      </Grid>
    </Window>
    

     

    And the converter will look like :

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Data;
    
    namespace ImageTest
    {
      public class Converter : IMultiValueConverter
      {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
          if (values[0] != null && values[1] != null)
          {
            double width = (double)values[0];
            double height = (double)values[1];
    
            return "Width: " + width + " - Height: " + height;
          }
          return string.Empty;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
          throw new NotImplementedException();
        }
      }
    }
    

    The good news is that you will no longer need code on your viewmodel.

    I didn't change much, i just binded to the actualwidth and actualheight properties of the image and wrote a converter to show the data.

     


    Best Regards,
    Tom

    If you have found this post helpful, please click the Vote as Helpful link (the green triangle and number on the top-left).
    If this post answers your question, click the Mark As Answered link below. It helps others who experience the same issue in future to find the solution.
    Thursday, April 29, 2010 12:55 PM
  • Hi and thanks for your replies,

    But...

    What I want is to be able to pass the image's size into my ViewModel and use it there for some logic.

    I used the TextBlock just to verify that the values are passed correctly.

    In other words, how can I bind the ActualWidth/ActualHeight in mode OneWayToSource???

    Thanks again...

    Thursday, April 29, 2010 2:44 PM
  • I think i found what you are looking for but i haven't tested this approach. You can look at: http://stackoverflow.com/questions/1083224/pushing-read-only-gui-properties-back-into-viewmodel
    Best Regards,
    Tom

    If you have found this post helpful, please click the Vote as Helpful link (the green triangle and number on the top-left).
    If this post answers your question, click the Mark As Answered link below. It helps others who experience the same issue in future to find the solution.
    • Marked as answer by pymWPF Sunday, May 02, 2010 6:49 AM
    Friday, April 30, 2010 10:00 AM