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();
}
}