Update label when checkbox in array checked - c#

I have a Boolean list that is bound to, displaying a list of checkboxes.
I now want to update a Label showing how many of the checkboxes are checked. This must update whenever any checkbox is checked.
I'm struggling as I don't know what to bind the checkbox to, so that I can update the string the label is bound to.
To do this, I think I need to bind each checkbox to a Command, which is working.
However, I can't work out how to update the label.
If there's a simpler way to do this (I'm sure there is) please let me know.
public class CheckBoxBoolean : INotifyPropertyChanged
{
public bool CheckBoxChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged("CheckBoxChecked");
}
}
public CheckBoxBoolean(bool isChecked)
{
_isChecked = isChecked;
}
private bool _isChecked = false;
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<StackPanel Grid.Row="0" Grid.Column="1">
<ItemsControl ItemsSource="{Binding Path=Patterns1}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=CheckBoxChecked, Mode=TwoWay}" Command="{Binding Path=DataContext.CheckBoxChanged, RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
private ICommand _checkBoxChanged;
public string Percentage1 { get; set; }
public ICommand CheckBoxChanged
{
get
{
if(_checkBoxChanged == null)
{
_checkBoxChanged = new CheckBoxChanging(Patterns1);
}
return _checkBoxChanged;
}
}
public class CheckBoxChanging : ICommand
{
public event EventHandler CanExecuteChanged;
private readonly ObservableCollection<CheckBoxBoolean> _Patterns;
public CheckBoxChanging(ObservableCollection<CheckBoxBoolean> items)
{
_Patterns = items;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
int i = 0;
foreach (CheckBoxBoolean chk in _Patterns)
{
if (chk.CheckBoxChecked)
i++;
}
Debug.WriteLine("UPD - Pattern 1 % = " + i / 16d);
}
}

Hi I just wrote an example for ur scenario take a look I think it will be helpful
Xaml
<StackPanel Grid.Row="0" Grid.Column="1">
<ItemsControl ItemsSource="{Binding Path=CBItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=CheckBoxChecked, Mode=TwoWay}" Command="{Binding Path=DataContext.CheckBoxChanged, RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Label Content="{Binding LabelContent}"></Label>
</StackPanel>
Ctro (setting datacontext)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MainWindowVM DC = new MainWindowVM();
DC.Init();
this.DataContext = DC;
}
}
Relay command and Model Class
class MainWindowVM : INotifyPropertyChanged
{
public MainWindowVM()
{
CheckBoxChanged = new RelayCommand(CheckBoxChangedMethod);
}
private string labelContent="Not Yet Checked";
public string LabelContent
{
get { return labelContent; }
set { labelContent = value; OnPropertyChanged(new PropertyChangedEventArgs("LabelContent")); }
}
public void Init()
{
try
{
CBItems = new ObservableCollection<ex>();
for (int i = 985; i <= 1030; i++)
CBItems.Add(new ex { CheckBoxChecked = true });
}
catch (Exception ex)
{
}
}
public ICommand CheckBoxChanged { get; set; }
private ObservableCollection<ex> _CBItems;
public ObservableCollection<ex> CBItems
{
get { return _CBItems; }
set
{
_CBItems = value;
OnPropertyChanged(new PropertyChangedEventArgs("CBItems"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
public void CheckBoxChangedMethod(object obj)
{
LabelContent = "You have Clicked the checkbox";
}
}
public class RelayCommand : ICommand
{
private Action<object> execute;
private Func<object, bool> canExecute;
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove { CommandManager.RequerySuggested -= value; }
}
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
//return this.canExecute == null || this.canExecute(parameter);
return true;
}
public void Execute(object parameter)
{
this.execute(parameter);
}
public RelayCommand(Action<object> execute)
{
this.execute = execute;
}
}
public class ex
{
private bool _checkBoxChecked;
public bool CheckBoxChecked
{
get { return _checkBoxChecked; }
set { _checkBoxChecked = value; }
}
}

Related

Checkbox binding WPF mvvm pattern

I have to bind the changes of checkbox in the listview.
checkbox should work in such a way that if i select all checkbox and uncheck a single checkbox then header checkbox should deselect. Same way if i have 3 child checkbox ,and individually select all then parent checkbox should select.
i am using MVVM pattern
xaml
<GridViewColumn Width="80" >
<GridViewColumn.Header >
<!--<CheckBox x:Name="cbSelectAll" IsChecked="{Binding ModelDetails.IsChecked}" Command="{Binding cbSelectAll_Checked}"/>-->
<CheckBox x:Name="cbSelectAll" Command="{Binding CbSelectAll_Checked}" IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}" />
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<WrapPanel x:Name="Layout" >
<CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay}" Command="{Binding CheckSingle}"/>
</WrapPanel>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
viewmodel.cs
public class Item : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
//publishing the event in current classs
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public Item(string name, string matches, string date, bool isSelected)
{
Name = name;
Type = matches;
Date = date;
IsSelected = isSelected;
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
public string Name { get; set; }
public string Type { get; set; }
public string Date { get; set; }
}
here is the another class
public class AddedFilesViewModel : INotifyPropertyChanged
{
public ICommand CbSelectAll_Checked { get; set; }
public ICommand UploadBtnClick { get; set; }
public ICommand CheckSingle { get; set; }
CbSelectAll_Checked = new RelayCommands(SelectAllBtnExecute, SelectAllBtnCanExecute);
UploadBtnClick = new RelayCommands(UploadBtnExecute, UploadBtnCanExecuteUpload);
CheckSingle = new RelayCommands(SingleCheckBoxExecute, SingleCheckBoxExecuteCanExecute);
public void SelectAllBtnExecute(object param)
{
if (selectedStatus == false)
{
foreach (var item in Items)
{
item.IsSelected = true;
}
selectedStatus = true;
}
else
{
foreach (var item in Items)
{
item.IsSelected = false;
}
selectedStatus = false;
}
}
public void SingleCheckBoxExecute(object param)
{
MessageBox.Show("hello");
}
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged("IsChecked");
}
}
public bool SelectAllBtnCanExecute(object param)
{
return true;
}
public void UploadBtnExecute(object param)
{
List<Item> selectedFiles = new List<Item>();
if (Items != null)
{
foreach (var selectedItems in Items)
{
if (selectedItems.IsSelected)
{
selectedFiles.Add(selectedItems);
}
}
I can see the following block need to be changed, Please share full xaml file so I can understand your data binding.
<CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay}" Command="{Binding CheckSingle}"/>
You need to edit it as "DataContext.IsSelected" and need to set binding source, it may be data grid or even full xaml based on your business logic to bind data. An example:
<CheckBox IsChecked="{Binding DataContext.IsSelected,Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Command="{Binding CheckSingle}"/>
I've just given sample example, there are many other ways to achive it.
Maybe I am saying shit but I would try that:
Remove all commands
in isChecked set I would put all you put in selectAllButtonExecute
in isChecked get I would check if all checkbox are checked and return true or false accordingly
in IsSelected set I would add OnPropertyChanged("IsChecked");

Deleting and Editing an item in a listview with Viewmodel and without using the codebehind

In the shown code i need to know the coding to be replaced in place of question mark in the code. I need to delete,edit and update the item in the list view without writing any code in code behind. I only want to do these operations by bindin view with view model through Icommand
This a class in my model Playlist.cs
namespace MvvmDemo.Models
{
public class Playlist
{
public string Title { get; set; }
}
}
This is a class in my viewmodel PlaylistsViewModel.cs
namespace MvvmDemo.ViewModels
{
public class PlaylistsViewModel
{
public ObservableCollection Playlists { get; private set; } = new ObservableCollection();
public ICommand AddPlaylistCommand { get; private set; }
public ICommand DeletePlaylistCommand { get; private set; }
public ICommand EditPlaylistCommand { get; private set; }
public PlaylistsViewModel()
{
AddPlaylistCommand = new Command(AddPlaylist);
DeletePlaylistCommand = new Command(DeletePlaylist);
}
public void AddPlaylist()
{
var newPlaylist = "Playlist " + (Playlists.Count + 1);
Playlists.Add(new Playlist { Title = newPlaylist });
}
public void DeletePlaylist()
{
????????????????
}
public void EditPlaylist()
{
????????????????
}
}
}
you have to make the command is parameterised and pass binding data through the parameter.
and from that data you can get the index value of selected.using that remove the item from the list.
Playlists.RemoveAt("INDEX_NUMBER");
To update it in the view use "INotifyProperty" also
If you want to delete and edit item in ListView, firstly, you should need to use ICommand, then you could need to use INotifyPropertyChanged to implement Inotify.
I do one sample that you can take a look. Choosing one Item and long press with the left mouse button, you will see two ways, delete Item and Edit Item action.
<ContentPage.Content>
<StackLayout>
<ListView
x:Name="mylistview"
ItemsSource="{Binding lists}"
SelectedItem="{Binding selecteditem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem
Command="{Binding BindingContext.DeletePlaylistCommand, Source={x:Reference Name=mylistview}}"
IsDestructive="true"
Text="Delete Item" />
<MenuItem
Command="{Binding BindingContext.EditPlaylistCommand, Source={x:Reference Name=mylistview}}"
IsDestructive="true"
Text="Edit Item" />
</ViewCell.ContextActions>
<StackLayout Padding="15,0">
<Label Text="{Binding Title}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Page19 : ContentPage, INotifyPropertyChanged
{
public ObservableCollection<Playlist> lists { get; set; }
//public RelayCommand1 AddPlaylistCommand { get; set; }
public RelayCommand DeletePlaylistCommand { get; set; }
public RelayCommand EditPlaylistCommand { get; set; }
private Playlist _selecteditem;
public Playlist selecteditem
{
get { return _selecteditem; }
set
{
_selecteditem = value;
RaisePropertyChanged("selecteditem");
}
}
public Page19 ()
{
InitializeComponent ();
lists = new ObservableCollection<Playlist>()
{
new Playlist(){Id=1,Title="list 1"},
new Playlist(){Id=2, Title="list 2"},
new Playlist(){Id=3,Title="list 3"},
new Playlist(){Id=4,Title="list 4"},
new Playlist(){Id=5,Title="list 5"},
new Playlist(){Id=6,Title="list 6"},
};
DeletePlaylistCommand = new RelayCommand(DeletePlaylist);
EditPlaylistCommand = new RelayCommand(EditPlaylist);
selecteditem = lists[0];
this.BindingContext = this;
}
public void AddPlaylist()
{
}
public void DeletePlaylist()
{
Playlist item = selecteditem;
lists.Remove(item);
}
public void EditPlaylist()
{
Playlist item = selecteditem;
int id = item.Id;
foreach(Playlist playl in lists.Where(a=>a.Id==id))
{
playl.Title = "chenge title";
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class Playlist: INotifyPropertyChanged
{
private int _Id;
public int Id
{
get { return _Id; }
set
{
_Id = value;
RaisePropertyChanged("Id");
}
}
private string _Title;
public string Title
{
get { return _Title;}
set
{
_Title = value;
RaisePropertyChanged("Title");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Here is the RelayCommd:
public class RelayCommand : ICommand
{
readonly Action _execute;
public RelayCommand(Action execute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_execute();
}
}
You can use observablecollection. It will reflect add,remove operation of item to the listview. And for editing item you have to raise property changed for all property you are editing.To simplify that property changed you can implement property changed event to your Playlist model class.
Like
public void DeletePlaylist()
{
Playlists.Remove(newPlaylist);
}
public void EditPlaylist()
{
newPlaylist.Title="Refreshed Playlist"
}
public class Playlist:INotifyPropertyChanged
{
private string title;
public string Title
{
get{return title;}
set{title=value;
NotifyPropertyChanged();}
}
}

How do I use a command in a user control

I am trying to use a command that I have created. I am using c# and the MVVM structure for my application. I have 1 Window (ApplicationView) that is used to display my userContols(MainWindow, Window1). On startup I have the MainWindow user control showing and there is a button on that user control that when you press will change the user contol from the main window usercontol to the Window1 userContol.
ApplicationView.xaml(Window)
<Window x:Class="Nmenq.ApplicationView"
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:Nmenq"
xmlns:my="clr-namespace:Nmenq"
Title="ApplicationView" Height="400" Width="575">
<Window.Resources>
<DataTemplate DataType="{x:Type local:MainWindowViewModel}">
<local:MainWindow/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Window1ViewModel}">
<local:Window1/>
</DataTemplate>
</Window.Resources>
<DockPanel LastChildFill="True">
<ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding CurrentPageViewModel}"/>
</DockPanel>
ApplicationView.xaml.cs
public partial class ApplicationView : Window
{
public ApplicationView()
{
InitializeComponent();
this.DataContext = new NavigationViewModel();
}
}
MainWindow.xaml(UserContol)
<UserControl x:Class="Nmenq.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:Nmenq"
xmlns:viewmodel="clr-namespace:Nmenq.ViewModel"
xmlns:my="clr-namespace:Nmenq"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="575">
<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
<Button x:Name="Accept_Button" Content="Accept" HorizontalAlignment="Left" Margin="475,316,0,0" VerticalAlignment="Top" Width="81" Command="{Binding Window1Command}"/>
</Grid>
MainWindow.xmal.cs
public partial class MainWindow : UserControl, INotifyPropertyChanged
{
NavigationViewModel object1 = new NavigationViewModel();
public ICommand Window1Command { get; set; }
public MainWindow()
{
InitializeComponent();
Window1Command = object1.Window1Command;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
NavigationViewModel(Where My command is set up)
class NavigationViewModel : INotifyPropertyChanged
{
public ICommand MainWindowCommand { get; set; }
public ICommand Window1Command { get; set; }
private object currentPageViewModel;
public object CurrentPageViewModel
{
get { return currentPageViewModel; }
set { currentPageViewModel = value; OnPropertyChanged("CurrentPageViewModel"); }
}
public NavigationViewModel()
{
MainWindowCommand = new BaseCommand(OpenMainWindow);
Window1Command = new BaseCommand(OpenWindow1);
CurrentPageViewModel = new MainWindowViewModel();
}
public void OpenMainWindow(object obj)
{
CurrentPageViewModel = new MainWindowViewModel();
}
public void OpenWindow1(object obj)
{
CurrentPageViewModel = new Window1ViewModel();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
public class BaseCommand : ICommand
{
private Predicate<object> _canExecute;
private Action<object> _method;
public event EventHandler CanExecuteChanged;
public BaseCommand(Action<object> method)
: this(method, null)
{
}
public BaseCommand(Action<object> method, Predicate<object> canExecute)
{
_method = method;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute == null)
{
return true;
}
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_method.Invoke(parameter);
}
} class NavigationViewModel : INotifyPropertyChanged
{
public ICommand MainWindowCommand { get; set; }
public ICommand Window1Command { get; set; }
private object currentPageViewModel;
public object CurrentPageViewModel
{
get { return currentPageViewModel; }
set { currentPageViewModel = value; OnPropertyChanged("CurrentPageViewModel"); }
}
public NavigationViewModel()
{
Window1Command = new BaseCommand(OpenWindow1);
CurrentPageViewModel = new MainWindowViewModel();
}
public void OpenWindow1(object obj)
{
CurrentPageViewModel = new Window1ViewModel();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
public class BaseCommand : ICommand
{
private Predicate<object> _canExecute;
private Action<object> _method;
public event EventHandler CanExecuteChanged;
public BaseCommand(Action<object> method)
: this(method, null)
{
}
public BaseCommand(Action<object> method, Predicate<object> canExecute)
{
_method = method;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute == null)
{
return true;
}
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_method.Invoke(parameter);
}
}
Any Help or advice would be greatly appreciated :)
You could bind directly to the Window1Command property of the NavigationViewModel and remove the Window1Command property from the UserControl:
<Button x:Name="Accept_Button" Content="Accept" HorizontalAlignment="Left" Margin="475,316,0,0" VerticalAlignment="Top" Width="81"
Command="{Binding DataContext.Window1Command, RelativeSource={RelativeSource AncestorType=Window}}"/>

listbox selected item returning Null value

I have a listbox which is binded to a Viewmodel, i am using mouse_doubeclickevent to retrieve the selected item value but its returning null, what i could be missing here ? SWdistinct is a list
ViewModel:
public List<swversion> SWdistinct
{
get;
set;
}
XAML:
<ListBox x:Name="CRSWUNIQUE" ItemsSource="{Binding SWdistinct}" SelectedItem="{Binding Path=SWdistinct,Mode=TwoWay}" MouseDoubleClick="CRSWUNIQUE_MouseDoubleClick" DisplayMemberPath="SW_Version" IsTextSearchEnabled="True" />
Code Behind:
private void CRSWUNIQUE_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
ListBoxItem item = CRSWUNIQUE.SelectedItem as ListBoxItem;
if (item != null)
// if (CRSWUNIQUE.SelectedItem != null)
{
MessageBox.Show(item.Content.ToString());
}
}
SelectedItem will give the object you bound. In this case it would be the object of swversion. Try below code.
private void CRSWUNIQUE_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var swversionitem = CRSWUNIQUE.SelectedItem as swversion;
if (swversionitem != null)
// if (CRSWUNIQUE.SelectedItem != null)
{
MessageBox.Show(swversionitem.SW_Version.ToString());
}
}
Sample for passing selecteditem to viewmodel on doubleclick. Try below code.
<ListBox ItemsSource="{Binding Swversions}" x:Name="lstListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding SW_Version}">
<TextBlock.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding ElementName=lstListBox,Path=DataContext.ListDoubleClickCommand}"
CommandParameter="{Binding ElementName=lstListBox, Path=SelectedItem}"/>
</TextBlock.InputBindings>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
class ViewModel
{
public List<swversion> Swversions { get; set; }
public ICommand ListDoubleClickCommand { get; set; }
public ViewModel()
{
Swversions = new List<swversion>()
{
new swversion() {SW_Version = "Version1"},
new swversion() {SW_Version = "Version2"},
new swversion() {SW_Version = "Version3"},
new swversion() {SW_Version = "Version4"},
new swversion() {SW_Version = "Version5"}
};
ListDoubleClickCommand = new RelayCommand(OnDoubleClick);
}
private void OnDoubleClick(object parameter)
{
}
}
class swversion
{
public string SW_Version { get; set; }
}
public class RelayCommand : ICommand
{
private Action<object> execute;
private Func<object, bool> canExecute;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return this.canExecute == null || this.canExecute(parameter);
}
public void Execute(object parameter)
{
this.execute(parameter);
}
}

XAML: Bind IsChecked to list object using an enum to index

I've read through probably 20 different posts and still can put together what I'm looking to do (maybe I'm going about it the wrong way?).
I want to make a window with a few checkboxes. These checkboxes need to have their IsChecked value bound to a member variable of an object in a List.
I'm trying something like this:
XAML
<CheckBox IsChecked="{Binding Features[0].Selected, Mode=TwoWay}">
<TextBlock Text="Feature 1" />
</CheckBox>
<CheckBox IsChecked="{Binding Features[1].Selected, Mode=TwoWay}">
<TextBlock Text="Feature 2" />
</CheckBox>
ViewModel
public static enum MyFeatureEnum
{
FEATURE1,
FEATURE2,
FEATURE3,
...
}
public class Feature : INotifyPropertyChanged
{
private bool _supported;
private bool _visible;
private bool _selected;
public MyFeatureEnum FeatureEnum { get; set; }
public bool Supported
{
get { return _supported; }
set { _supported = value; NotifyPropertyChanged("Supported"); }
}
public bool Visible
{
get { return _visible; }
set { _visible = value; NotifyPropertyChanged("Visible"); }
}
public bool Selected
{
get { return _selected; }
set { _selected = value; NotifyPropertyChanged("Selected"); }
}
public Feature(MyFeatureEnum featureEnum)
{
_supported = false;
_visible = false;
_selected = false;
FeatureEnum = featureEnum;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public List<Feature> Features { get; set; }
public InstallViewModel()
{
...
// Generate the list of features
Features = new List<Feature>();
foreach (MyFeatureEnum f in Enum.GetValues(typeof(MyFeatureEnum)))
{
Features.Add(new Feature(f));
}
...
}
This works.
What I want is to replace:
<CheckBox IsChecked="{Binding Features[0].Selected, Mode=TwoWay}">
with something like:
<CheckBox IsChecked="{Binding Features[InstallViewModel.MyFeatureEnum.FEATURE1].Selected, Mode=TwoWay}">
Is this possible?
Is this possible?
Not using a List<Feature> but you could use a Dictionary<MyFeatureEnum, Feature>:
public class InstallViewModel
{
public Dictionary<MyFeatureEnum, Feature> Features { get; set; }
public InstallViewModel()
{
// Generate the list of features
Features = new Dictionary<MyFeatureEnum, Feature>();
foreach (MyFeatureEnum f in Enum.GetValues(typeof(MyFeatureEnum)))
{
Features.Add(f, new Feature(f));
}
}
}
<CheckBox IsChecked="{Binding Features[FEATURE1].Selected, Mode=TwoWay}" />

Categories

Resources