Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. WPF
  4. [Problem] Why can not Pass Image between 2 Views by using the same ViewModel (MVVM)

[Problem] Why can not Pass Image between 2 Views by using the same ViewModel (MVVM)

Scheduled Pinned Locked Moved WPF
wpfhelpquestiondatabaseregex
10 Posts 4 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    Oscar Tsai
    wrote on last edited by
    #1

    The purpose of this code is open image file in a page and display it in another page. I had tried set ViewModel by using Singleton Pattern, but it didn't work.... If I integrate to one View, it can display the image correctly. But I need to separate the views. I have no idea what's wrong in this MVVM code....and how to fix it? Please point me how can I do or let me know what keyword I can search the toturial/sample. Thank you all. -- The OpenFile button is on DisplayControlView and display on DisplayView. The View Schema is as below: MainWindow.xaml (window) | |__ReviewView.xaml (page)   |   |__DisplayControlView.xaml (page)   |   |__DisplayPanelView.xaml (page)     |     |__DisplayView.xaml (page) -- DisplayControlView.xaml

    ...
    ...

    -- DisplayView.xaml

    ...

    ...

    -- DisplayViewModel.cs

    class DisplayViewModel : ViewModelBase
    {
    private DisplayImageModel image { get; set; }

    private ObservableCollection imagelist = new ObservableCollection();
    public ObservableCollection ImageList
    {
    	get { return imagelist; }
    	set
    	{
    		imagelist = value;
    		OnPropertyChanged();
    	}
    }
    
    public string ImagePath
    {
    	get { return image.Path; }
    	set
    	{
    		if (image.Path != value)
    		{
    			image.Path = value;
    			OnPropertyChanged();
    		}
    	}
    }
    
    public DisplayViewModel()
    {
    	image = new DisplayImageModel();
    	ImagePath = @"C:\\Users\\oscartsai\\Desktop\\lenna.png";
    }
    
    public bool CanExecute()
    {
    	return true;
    }
    
    public RelayCommand OpenFile
    {
    	get { return new RelayCommand(openFile, CanExecute); }
    }
    
    private void openFile()
    {
    	string\[\] picExtName = new string\[\] { ".PNG", ".JPG", "JEPG", "BMP" };
    
    	OpenFileDialog dlgOpenFile = new OpenFileDialog() 
    	{ Filter = "Picture|\*.jpg;\*.jpeg;\*.bmp;\*.png|All File|\*.\*" };
    	if (dlgOpenFile.ShowDialog() != true)
    	{
    		return;
    	}
    	if (picExtName.Any(System.IO.Path.GetExtension(dlgO
    
    L Richard DeemingR M 3 Replies Last reply
    0
    • O Oscar Tsai

      The purpose of this code is open image file in a page and display it in another page. I had tried set ViewModel by using Singleton Pattern, but it didn't work.... If I integrate to one View, it can display the image correctly. But I need to separate the views. I have no idea what's wrong in this MVVM code....and how to fix it? Please point me how can I do or let me know what keyword I can search the toturial/sample. Thank you all. -- The OpenFile button is on DisplayControlView and display on DisplayView. The View Schema is as below: MainWindow.xaml (window) | |__ReviewView.xaml (page)   |   |__DisplayControlView.xaml (page)   |   |__DisplayPanelView.xaml (page)     |     |__DisplayView.xaml (page) -- DisplayControlView.xaml

      ...
      ...

      -- DisplayView.xaml

      ...

      ...

      -- DisplayViewModel.cs

      class DisplayViewModel : ViewModelBase
      {
      private DisplayImageModel image { get; set; }

      private ObservableCollection imagelist = new ObservableCollection();
      public ObservableCollection ImageList
      {
      	get { return imagelist; }
      	set
      	{
      		imagelist = value;
      		OnPropertyChanged();
      	}
      }
      
      public string ImagePath
      {
      	get { return image.Path; }
      	set
      	{
      		if (image.Path != value)
      		{
      			image.Path = value;
      			OnPropertyChanged();
      		}
      	}
      }
      
      public DisplayViewModel()
      {
      	image = new DisplayImageModel();
      	ImagePath = @"C:\\Users\\oscartsai\\Desktop\\lenna.png";
      }
      
      public bool CanExecute()
      {
      	return true;
      }
      
      public RelayCommand OpenFile
      {
      	get { return new RelayCommand(openFile, CanExecute); }
      }
      
      private void openFile()
      {
      	string\[\] picExtName = new string\[\] { ".PNG", ".JPG", "JEPG", "BMP" };
      
      	OpenFileDialog dlgOpenFile = new OpenFileDialog() 
      	{ Filter = "Picture|\*.jpg;\*.jpeg;\*.bmp;\*.png|All File|\*.\*" };
      	if (dlgOpenFile.ShowDialog() != true)
      	{
      		return;
      	}
      	if (picExtName.Any(System.IO.Path.GetExtension(dlgO
      
      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      You've got a .Contains function with no parameter.

      if (picExtName.Any(System.IO.Path.GetExtension(dlgOpenFile.FileName).ToUpper().Contains))

      It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

      O 1 Reply Last reply
      0
      • L Lost User

        You've got a .Contains function with no parameter.

        if (picExtName.Any(System.IO.Path.GetExtension(dlgOpenFile.FileName).ToUpper().Contains))

        It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

        O Offline
        O Offline
        Oscar Tsai
        wrote on last edited by
        #3

        It uses String[].Any() to indicate the parameter. The problem is it can't display selected image file on DisplayView (page).... As my original post mention, all the same code can work well in one ViewModel and one View. When I separate the code to one ViewModel and 3 Views, it can not work as my expected. It just can show open dialog for selecting file, but display nothing after selection. I think the problem will be the operation on one View(DisplayControlView) can not effect another View(DisplayView)

        L 1 Reply Last reply
        0
        • O Oscar Tsai

          It uses String[].Any() to indicate the parameter. The problem is it can't display selected image file on DisplayView (page).... As my original post mention, all the same code can work well in one ViewModel and one View. When I separate the code to one ViewModel and 3 Views, it can not work as my expected. It just can show open dialog for selecting file, but display nothing after selection. I think the problem will be the operation on one View(DisplayControlView) can not effect another View(DisplayView)

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          I use code-behind to load images; that works. I also hook up the "ImageFailed" event; then you know why it's not working (somewhat). (MVVM has too much "indirection" for my brain).

          It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food

          1 Reply Last reply
          0
          • O Oscar Tsai

            The purpose of this code is open image file in a page and display it in another page. I had tried set ViewModel by using Singleton Pattern, but it didn't work.... If I integrate to one View, it can display the image correctly. But I need to separate the views. I have no idea what's wrong in this MVVM code....and how to fix it? Please point me how can I do or let me know what keyword I can search the toturial/sample. Thank you all. -- The OpenFile button is on DisplayControlView and display on DisplayView. The View Schema is as below: MainWindow.xaml (window) | |__ReviewView.xaml (page)   |   |__DisplayControlView.xaml (page)   |   |__DisplayPanelView.xaml (page)     |     |__DisplayView.xaml (page) -- DisplayControlView.xaml

            ...
            ...

            -- DisplayView.xaml

            ...

            ...

            -- DisplayViewModel.cs

            class DisplayViewModel : ViewModelBase
            {
            private DisplayImageModel image { get; set; }

            private ObservableCollection imagelist = new ObservableCollection();
            public ObservableCollection ImageList
            {
            	get { return imagelist; }
            	set
            	{
            		imagelist = value;
            		OnPropertyChanged();
            	}
            }
            
            public string ImagePath
            {
            	get { return image.Path; }
            	set
            	{
            		if (image.Path != value)
            		{
            			image.Path = value;
            			OnPropertyChanged();
            		}
            	}
            }
            
            public DisplayViewModel()
            {
            	image = new DisplayImageModel();
            	ImagePath = @"C:\\Users\\oscartsai\\Desktop\\lenna.png";
            }
            
            public bool CanExecute()
            {
            	return true;
            }
            
            public RelayCommand OpenFile
            {
            	get { return new RelayCommand(openFile, CanExecute); }
            }
            
            private void openFile()
            {
            	string\[\] picExtName = new string\[\] { ".PNG", ".JPG", "JEPG", "BMP" };
            
            	OpenFileDialog dlgOpenFile = new OpenFileDialog() 
            	{ Filter = "Picture|\*.jpg;\*.jpeg;\*.bmp;\*.png|All File|\*.\*" };
            	if (dlgOpenFile.ShowDialog() != true)
            	{
            		return;
            	}
            	if (picExtName.Any(System.IO.Path.GetExtension(dlgO
            
            Richard DeemingR Offline
            Richard DeemingR Offline
            Richard Deeming
            wrote on last edited by
            #5

            Quote:

            DisplayView.xaml

            <Page.DataContext>
            vm:DisplayViewModel/
            </Page.DataContext>
            ...
            <Image x:Name="imgDisplayView" Source="{Binding ImagePath}">
            <Image.RenderTransform>
            <TransformGroup>
            <TranslateTransform/>
            <RotateTransform/>
            <ScaleTransform/>
            </TransformGroup>
            </Image.RenderTransform>
            </Image>
            ...

            The problem is that your DisplayPanelView is setting its DataContext to a new instance of your viewmodel. The image path you set on the DataContext of the DisplayControlView will have no effect on the property of the separate viewmodel instance used as the DataContext for DisplayPanelView. You need both controls to use the same viewmodel instance for their DataContext. Depending on how your ReviewView viewmodel is set up, you probably want to expose a single DisplayViewModel instance as a property on that viewmodel, and have both Display... views bound to that. For example:

            public class ReviewViewModel : ViewModelBase
            {
            private DisplayViewModel _display = new DisplayViewModel();

            public DisplayViewModel
            {
                get { return \_display; }
                set { SetValue(ref \_display, value); }
            }
            

            }

            ReviewView.xaml:

            <views:DisplayControlView DataContext="{Binding Path=DisplayViewModel}" />
            <views:DisplayPanelView DataContext="{Binding Path=DisplayPanelView}" />

            Remove the <Page.DataContext> from both DisplayControlView and DisplayPanelView pages.


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

            O 1 Reply Last reply
            0
            • Richard DeemingR Richard Deeming

              Quote:

              DisplayView.xaml

              <Page.DataContext>
              vm:DisplayViewModel/
              </Page.DataContext>
              ...
              <Image x:Name="imgDisplayView" Source="{Binding ImagePath}">
              <Image.RenderTransform>
              <TransformGroup>
              <TranslateTransform/>
              <RotateTransform/>
              <ScaleTransform/>
              </TransformGroup>
              </Image.RenderTransform>
              </Image>
              ...

              The problem is that your DisplayPanelView is setting its DataContext to a new instance of your viewmodel. The image path you set on the DataContext of the DisplayControlView will have no effect on the property of the separate viewmodel instance used as the DataContext for DisplayPanelView. You need both controls to use the same viewmodel instance for their DataContext. Depending on how your ReviewView viewmodel is set up, you probably want to expose a single DisplayViewModel instance as a property on that viewmodel, and have both Display... views bound to that. For example:

              public class ReviewViewModel : ViewModelBase
              {
              private DisplayViewModel _display = new DisplayViewModel();

              public DisplayViewModel
              {
                  get { return \_display; }
                  set { SetValue(ref \_display, value); }
              }
              

              }

              ReviewView.xaml:

              <views:DisplayControlView DataContext="{Binding Path=DisplayViewModel}" />
              <views:DisplayPanelView DataContext="{Binding Path=DisplayPanelView}" />

              Remove the <Page.DataContext> from both DisplayControlView and DisplayPanelView pages.


              "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

              O Offline
              O Offline
              Oscar Tsai
              wrote on last edited by
              #6

              Here is something can't run properly. Is below code is written in NEW class called ReviewViewModel?

              public class ReviewViewModel : ViewModelBase
              {
              private DisplayViewModel _display = new DisplayViewModel();

              public DisplayViewModel
              {
                  get { return \_display; }
                  set { SetValue(ref \_display, value); }
              }
              

              }

              But the Intellisense will show warning about the declaration of DisplayViewModel and the function of SetValue is invalid.... What prerequisites are needed for this code? Sincere thank Richard Master to point me!! All Views need one ViewModel instance, and I had no idea about how to set one ViewModel instance until this post point me. And thank Gerry join this discussion.

              O 1 Reply Last reply
              0
              • O Oscar Tsai

                Here is something can't run properly. Is below code is written in NEW class called ReviewViewModel?

                public class ReviewViewModel : ViewModelBase
                {
                private DisplayViewModel _display = new DisplayViewModel();

                public DisplayViewModel
                {
                    get { return \_display; }
                    set { SetValue(ref \_display, value); }
                }
                

                }

                But the Intellisense will show warning about the declaration of DisplayViewModel and the function of SetValue is invalid.... What prerequisites are needed for this code? Sincere thank Richard Master to point me!! All Views need one ViewModel instance, and I had no idea about how to set one ViewModel instance until this post point me. And thank Gerry join this discussion.

                O Offline
                O Offline
                Oscar Tsai
                wrote on last edited by
                #7

                In addition: ReviewView.xaml

                1 Reply Last reply
                0
                • O Oscar Tsai

                  The purpose of this code is open image file in a page and display it in another page. I had tried set ViewModel by using Singleton Pattern, but it didn't work.... If I integrate to one View, it can display the image correctly. But I need to separate the views. I have no idea what's wrong in this MVVM code....and how to fix it? Please point me how can I do or let me know what keyword I can search the toturial/sample. Thank you all. -- The OpenFile button is on DisplayControlView and display on DisplayView. The View Schema is as below: MainWindow.xaml (window) | |__ReviewView.xaml (page)   |   |__DisplayControlView.xaml (page)   |   |__DisplayPanelView.xaml (page)     |     |__DisplayView.xaml (page) -- DisplayControlView.xaml

                  ...
                  ...

                  -- DisplayView.xaml

                  ...

                  ...

                  -- DisplayViewModel.cs

                  class DisplayViewModel : ViewModelBase
                  {
                  private DisplayImageModel image { get; set; }

                  private ObservableCollection imagelist = new ObservableCollection();
                  public ObservableCollection ImageList
                  {
                  	get { return imagelist; }
                  	set
                  	{
                  		imagelist = value;
                  		OnPropertyChanged();
                  	}
                  }
                  
                  public string ImagePath
                  {
                  	get { return image.Path; }
                  	set
                  	{
                  		if (image.Path != value)
                  		{
                  			image.Path = value;
                  			OnPropertyChanged();
                  		}
                  	}
                  }
                  
                  public DisplayViewModel()
                  {
                  	image = new DisplayImageModel();
                  	ImagePath = @"C:\\Users\\oscartsai\\Desktop\\lenna.png";
                  }
                  
                  public bool CanExecute()
                  {
                  	return true;
                  }
                  
                  public RelayCommand OpenFile
                  {
                  	get { return new RelayCommand(openFile, CanExecute); }
                  }
                  
                  private void openFile()
                  {
                  	string\[\] picExtName = new string\[\] { ".PNG", ".JPG", "JEPG", "BMP" };
                  
                  	OpenFileDialog dlgOpenFile = new OpenFileDialog() 
                  	{ Filter = "Picture|\*.jpg;\*.jpeg;\*.bmp;\*.png|All File|\*.\*" };
                  	if (dlgOpenFile.ShowDialog() != true)
                  	{
                  		return;
                  	}
                  	if (picExtName.Any(System.IO.Path.GetExtension(dlgO
                  
                  M Offline
                  M Offline
                  michaelbarb
                  wrote on last edited by
                  #8

                  One thing I see right off the bat is that when you use DataContext you are instantiating DisplayViewModel.

                  You basically created two instances of DisplayViewModel. One fix would be to instantiate it somewhere else in C# :

                  DisplayViewModel displayViewModel = new DisplayViewModel();

                  Then add to each page then for each page in C# on initialization add:

                  this.DataContext = ????.displayViewModel

                  Now they will both point to the same instance.

                  So many years of programming I have forgotten more languages than I know.

                  O 1 Reply Last reply
                  0
                  • M michaelbarb

                    One thing I see right off the bat is that when you use DataContext you are instantiating DisplayViewModel.

                    You basically created two instances of DisplayViewModel. One fix would be to instantiate it somewhere else in C# :

                    DisplayViewModel displayViewModel = new DisplayViewModel();

                    Then add to each page then for each page in C# on initialization add:

                    this.DataContext = ????.displayViewModel

                    Now they will both point to the same instance.

                    So many years of programming I have forgotten more languages than I know.

                    O Offline
                    O Offline
                    Oscar Tsai
                    wrote on last edited by
                    #9

                    Thank for point me. Actually, I had solved this problem a few moment ago... XD Here is my solution: 1. Using singleton-pattern to fix one execution instance 2. At each View code-behind(???.xmal.cs) which needs to using the same ViewModel, I add below code

                    this.context = viewmodel.instance

                    BTW, I also ask in below Taiwan IT forum......and self-question at below to show my detail solution XD [問題] MVVM架構下,如何多個View共用同一個ViewModel變數 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天[^] For you reference~~~ Thanks guys again :)

                    M 1 Reply Last reply
                    0
                    • O Oscar Tsai

                      Thank for point me. Actually, I had solved this problem a few moment ago... XD Here is my solution: 1. Using singleton-pattern to fix one execution instance 2. At each View code-behind(???.xmal.cs) which needs to using the same ViewModel, I add below code

                      this.context = viewmodel.instance

                      BTW, I also ask in below Taiwan IT forum......and self-question at below to show my detail solution XD [問題] MVVM架構下,如何多個View共用同一個ViewModel變數 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天[^] For you reference~~~ Thanks guys again :)

                      M Offline
                      M Offline
                      michaelbarb
                      wrote on last edited by
                      #10

                      I have also seen static's used. Not a "static" fan but it works. Static's have there place. The reason Serilog is so easy to use and hence popular is because of static's.

                      So many years of programming I have forgotten more languages than I know.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups