1

I'm trying to transition from WinForm to WPF, and while studying this topic i came across this challenge,

change combobox items upon a button click and create a button that shows the original selected value"

I managed to do this with inline RelayCommand but it seems to me that I'm breaking the MVVM pattern and also it does not comply to that part "button that shows the original selected value", so i continued reading and i found out that i can use IValueConverter. But i cannot figure out to connect between the button click and the converter(is this even possible, or i need to do something else?)

my viewModel

 class MainWindowVM : INotifyPropertyChanged
    {
        public MainWindowVM()
        {
            CBItems = new ObservableCollection<double>();
            for (int i = 985; i <= 1030; i++)
                CBItems.Add(i);
            CBSelectedValue = 1013;

            testCmd = new RelayCommand(p =>
            {
                for (int i = 0; i < CBItems.Count; i++)
                { 
                    if(p.Equals("inHg"))
                    {
                        CBItems[i] *= 33.86;
                        ConversionUnit = "milibar";
                    }
                    else
                    {
                        CBItems[i] /= 33.86;
                        ConversionUnit = "inHg";
                    }
                }
            }
        );

            SetQNH = new RelayCommand(p => MessageBox.Show(string.Format("QNH = {0}", Convert.ToInt32(p))));

        }

        public RelayCommand SetQNH { get; set; }         
        public RelayCommand testCmd { get; set; }


        private ObservableCollection<double> _CBItems;
        public ObservableCollection<double> CBItems
        {
            get { return _CBItems; }
            set
            {
                _CBItems = value;
                OnPropertyChanged("CBItems");
            }
        }

        private string _conversionUnit;

        public string ConversionUnit
        {
            get { return _conversionUnit; }
            set
            {
                _conversionUnit = value;
                OnPropertyChanged("ConversionUnit");
            }
        }

        private int _CBSelectedValue;
        public int CBSelectedValue {
            get { return _CBSelectedValue; }
            set
            {
                _CBSelectedValue = value;
                OnPropertyChanged("CBSelectedValue");                  
            }
        }

        private void OnPropertyChanged(string s)
        {
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(s));
        }

        public event PropertyChangedEventHandler PropertyChanged;             
    }
}

my window

<Window x:Class="QNH.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:QNH"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        mc:Ignorable="d"
        Title="MainWindow" Height="318" Width="638">
    <Window.Resources>
        <local:IUnitsValueConverter x:Key="MyConverter" />
    </Window.Resources>
    <Window.DataContext>
        <local:MainWindowVM/>
    </Window.DataContext>
    <Grid>
        <ComboBox  Name="cb" ItemsSource="{Binding CBItems}" SelectedItem="{Binding CBSelectedValue}" HorizontalAlignment="Left" Margin="406,136,0,0" VerticalAlignment="Top" Width="120" >
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Converter={StaticResource MyConverter} }"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>

        </ComboBox>


        <Button Name="Unit" Content="{Binding ConversionUnit, TargetNullValue=inHg}"
                Command="{Binding testCmd}" CommandParameter="{Binding ElementName=Unit, Path=Content}"
                HorizontalAlignment="Left" Margin="140,136,0,0" VerticalAlignment="Top" Width="75"/>
        <Button Content="SET" Command="{Binding SetQNH}" CommandParameter="{Binding ElementName=cb, Path=SelectedValue}" HorizontalAlignment="Left" Margin="406,163,0,0" VerticalAlignment="Top" Width="75"/>
    </Grid>
</Window>

and my converter

[ValueConversion(typeof(int), typeof(double))]
    public class IUnitsValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //var val = (int?)value;
            //if (val == null)
            //    return -1;

            return value;//* 33.86;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
styx
  • 1,852
  • 1
  • 11
  • 22
  • Why would using a RelayCommand breakt the MVVM pattern? – mm8 Apr 18 '19 at 08:35
  • @mm8 i really don't know, i copied from some examples i found – styx Apr 18 '19 at 08:36
  • What exactly are you asking here? What are you trying to accomplish? – mm8 Apr 18 '19 at 08:37
  • @mm8 im trying to solve this challenge(as written the original post) **change combobox items upon a button click and create a button that shows the original selected value** – styx Apr 18 '19 at 08:38
  • 1
    And where does the converter come in? What's wrong with your current code? – mm8 Apr 18 '19 at 08:39
  • @mm8 what do you mean? and its wrong because, as i said it breaks the part of "button that shows the original selected value" – styx Apr 18 '19 at 08:41
  • So don't set the `ConversionUnit` in the `Execute` method of the command? Or bind the `Content` property to `CBSelectedValue`? Also, the `CommandParameter` seems unecessary since you can access the `ConversionUnit` property directly in the `Execute` method. – mm8 Apr 18 '19 at 08:42
  • @styx on button click set `CBSelectedValue=CBItems[0]` it will change on UI. note I used 0 as an example – Avinash Reddy Apr 18 '19 at 08:45
  • @mm8 i have a hard time following what you are trying to say, if you may show me what you mean – styx Apr 18 '19 at 08:48
  • @Avinash why should i do it, isnt `OnPropertyChanged` should do it? – styx Apr 18 '19 at 08:54
  • @styx `OnPropertyChanged` will update the UI from VM but on button click, u wanna change `ComboBox` item how that will work? – Avinash Reddy Apr 18 '19 at 08:57
  • @Avinash i dont know, and it seems the UI does not update – styx Apr 18 '19 at 09:07
  • @styx I'm still confused what ur trying to do just let me know wt ur trying to do I will try to give an example as ur still new – Avinash Reddy Apr 18 '19 at 09:40
  • @Avinash Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/192041/discussion-between-styx-and-avinash). – styx Apr 18 '19 at 10:38

0 Answers0