question

essamce avatar image
0 Votes"
essamce asked essamce edited

enum in xaml in MVVVM

hi

 <MenuItem Header="StepOne"
     Command="{Binding CurrentStepCmd}"
     CommandParameter="{x:Static data:Steps.StepOne}"/>
 <MenuItem Header="StepTwo"
     Command="{Binding CurrentStepCmd}"
     CommandParameter="{x:Static data:Steps.StepTwo}"/>


code works fine but:
Q1: i don't like my xaml to access any data from outside it's viewmodel (i don't like to include the
namespace "data" in xaml ).
Q2: is the solution of making ICommand for each enum value (Steps enum) better than using one cmd with param?


i'm using C# and wpf .Net framwork 4.7 app
any help will be appreciated,

windows-wpfdotnet-wpf-xaml
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

DaisyTian-1203 avatar image
1 Vote"
DaisyTian-1203 answered essamce edited

I make a demo to implement the data in ViewModel like below:
Xaml code is:

    <Window.Resources>
     <HierarchicalDataTemplate DataType="{x:Type local:UserModel}">
         <MenuItem Header="{Binding Path=UserName}" Command="{Binding Path=ShowCommand}" CommandParameter="{Binding Path=UserAge}"/>
     </HierarchicalDataTemplate>
 </Window.Resources>
    
 <Window.DataContext>
     <local:MainViewModel></local:MainViewModel>
 </Window.DataContext>
 <StackPanel>
     <Menu ItemsSource="{Binding LtUser}"></Menu>
 </StackPanel>

The C# code is:

 using GalaSoft.MvvmLight;
 using GalaSoft.MvvmLight.Command;
 using System.Collections.ObjectModel;
 using System.Windows;
 using System.Windows.Input;
    
 namespace CommandParameterMVVM
 {
     public class MainViewModel:ViewModelBase
     {
         private ObservableCollection<UserModel> _LtUser;
         public ObservableCollection<UserModel> LtUser
         {
             get { return _LtUser; }
             set
             {
                 if (_LtUser != value)
                 {
                     _LtUser = value;
                     RaisePropertyChanged("LtUser");
                 }
             }
         }
    
         public MainViewModel()
         {
             LtUser = new ObservableCollection<UserModel>()
             {
                 new UserModel(){UserName="Name1",UserAge="11"},
                 new UserModel(){UserName="Name2",UserAge="12"},
                 new UserModel(){UserName="Name3",UserAge="13"},
                 new UserModel(){UserName="Name4",UserAge="14"}
             };
         } 
     }
    
    
     public class UserModel : ViewModelBase
     {
         private string _UserName;
         public string UserName
         {
             get { return _UserName; }
             set
             {
                 if (_UserName != value)
                 {
                     _UserName = value;
                     RaisePropertyChanged("UserName");
                 }
             }
         }
    
    
         private string _UserAge;
         public string UserAge
         {
             get { return _UserAge; }
             set
             {
                 if (_UserAge != value)
                 {
                     _UserAge = value;
                     RaisePropertyChanged("UserAge");
                 }
             }
         }
    
         public ICommand ShowCommand { get { return new RelayCommand<string>(OnShow); } }
    
         private void OnShow(string obj)
         {
             MessageBox.Show("Age is:"+obj.ToString());
         }
     }
 }

The result is:
81443-2.gif

Did it give you some help? If it does not, please give me more description to analyze.


If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.



2.gif (117.0 KiB)
· 7
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

hi @DaisyTian-MSFT
thanks for your reply man, but the part LtUser[i] in xaml isn't fun because i don't like magic number i'm looking for smth more declarative and that's why we use enum or commands in the first place.

0 Votes 0 ·

@essamce
I have updated the answer for you, please check it and let me know it is helpful for you or not.

1 Vote 1 ·

hi @DaisyTian-MSFT
bro this is cool i'll give it try and back to you, appreciate it man.

0 Votes 0 ·

hi @DaisyTian-MSFT
brilliant solution and i learned new thing HierarchicalDataTemplate, but unfortunately it doesn't give the Hierarchical view it gives one level (all item in same level) , is it possible to get a Hierarchical view ?

0 Votes 0 ·

hi @DaisyTian-MSFT
based on your ides i came up with this:




0 Votes 0 ·
 <Window.Resources>
           
            
         <DataTemplate x:Key="template1" DataType="{x:Type local:UserModel}">
             <MenuItem 
                 Header="{Binding Path=UserName}" 
                 Command="{Binding Path=ShowCommand}" 
                 CommandParameter="{Binding Path=UserAge}"/>
         </DataTemplate>
     </Window.Resources>
    
     <StackPanel>
         <!--<Menu ItemsSource="{Binding LtUser}"></Menu>-->
         <Menu>
             <MenuItem Header="User1and2">
                 <ContentControl Content="{Binding User1}" ContentTemplate="{StaticResource template1}"/>
             </MenuItem>
         </Menu>
     </StackPanel>
0 Votes 0 ·

but it seems like i just over engineered the problem, i'll go with the a simple solution maybe the original one or the solution anonymous user-3316 suggested,
thank you so much man.

0 Votes 0 ·
PeterFleischer-3316 avatar image
1 Vote"
PeterFleischer-3316 answered essamce commented

Hi,
you can you a simple string as Parameter:

  <MenuItem Header="StepOne"
      Command="{Binding CurrentStepCmd}"
      CommandParameter="StepOne}"/>
  <MenuItem Header="StepTwo"
      Command="{Binding CurrentStepCmd}"
      CommandParameter="StepTwo"/>

and in IComand.Execute use switch (Select) with state.ToString()

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

hi anonymous user-3316
thanks for your reply bro, since the names (StepOne, StepTwo) isn't actually the original names and it's smth like (AcadPolylineFalttenToolMultiple...) and it would be a lot of copy/paste from viewmodel to xaml,
but your solution still the simplest and the cleanest one so far, appreciate it bro.

0 Votes 0 ·