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}}"/>
Related
I have been trying to figure out these past 2 days how to switch between 2 User Controls back and forward with buttons inside those User Controls.
I managed to make this happen but with the buttons outside those User Controls.
This is how my project files look
BaseCommand.cs
public class BaseCommand : ICommand
{
private Action<object> _method;
public event EventHandler CanExecuteChanged;
public BaseCommand(Action<object> method)
{
_method = method;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_method.Invoke(parameter);
}
}
MainViewModel.cs
class MainViewModel : INotifyPropertyChanged
{
public ICommand LogInCommand { get; set; }
public ICommand SetupCommand { get; set; }
private object selectedViewModel;
public object SelectedViewModel
{
get { return selectedViewModel; }
set { selectedViewModel = value; OnPropertyChanged("SelectedViewModel"); }
}
public MainViewModel()
{
LogInCommand = new BaseCommand(OpenLogIn);
SetupCommand = new BaseCommand(OpenSetup);
}
private void OpenLogIn(object obj)
{
SelectedViewModel = new LogInViewModel();
}
private void OpenSetup(object obj)
{
SelectedViewModel = new SetupViewModel();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
MainWindow.xaml
<StackPanel>
<ContentControl Content="{Binding SelectedViewModel}"/>
<Button Content="Open LogIn" Height="24" Command="{Binding LogInCommand}"/>
<Button Content="Open Setup" Height="24" Command="{Binding SetupCommand}"/>
</StackPanel>
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
LoginViewModel and SetupViewModel are empty classes and their corresponding views have a text block indicating what they are.
What I want is to have instead 2 buttons in my MainWindow.xaml I want 1 in my LogInView.xaml that opens SetupView.xaml and vice versa.
App.xaml
<Application.Resources>
<DataTemplate DataType="{x:Type viewmodels:LogInViewModel}">
<views:LogInView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:SetupViewModel}">
<views:SetupView/>
</DataTemplate>
</Application.Resources>
Move "Open Setup" button to LogInView and "Open LogIn" button to SetupView.
In LogInViewModel create SetupCommand and pass the MainViewModel in the ctor. When the button "Open Setup" is clicked and SetupCommand is invoked then call new OpenSetup method on the MainViewModel.
public class LogInViewModel : INotifyPropertyChanged // etc.
{
private readonly MainViewModel mainViewModel;
public ICommand SetupCommand { get; set; }
public LogInViewModel(MainViewModel mainViewModel)
{
this.mainViewModel = mainViewModel;
SetupCommand = new BaseCommand(OpenSetup);
}
private void OpenSetup(object obj)
{
mainViewModel.OpenSetup();
}
....
}
Similar for SetupViewModel
public class SetupViewModel : INotifyPropertyChanged // etc.
{
private readonly MainViewModel mainViewModel;
public ICommand LogInCommand { get; set; }
public SetupViewModel(MainViewModel mainViewModel)
{
this.mainViewModel = mainViewModel;
LogInCommand = new BaseCommand(OpenLogIn);
}
private void OpenLogIn(object obj)
{
mainViewModel.OpenLogIn();
}
....
}
Finally, remove commands from MainViewModel, modify OpenLogIn and OpenSetup methods and pass reference to the MainViewModel when you create new instance of LogInViewModel or SetupViewModel.
public class MainViewModel : INotifyPropertyChanged
{
private object selectedViewModel;
public object SelectedViewModel
{
get { return selectedViewModel; }
set { selectedViewModel = value; OnPropertyChanged("SelectedViewModel"); }
}
public MainViewModel()
{
OpenLogIn();
}
public void OpenLogIn()
{
SelectedViewModel = new LogInViewModel(this);
}
public void OpenSetup()
{
SelectedViewModel = new SetupViewModel(this);
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
MainWindow.xaml:
<TextBox HorizontalAlignment="Left" Height="23" Margin="308,90,0,0" TextWrapping="Wrap" Text = "{Binding Login, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
MainWindow.cs:
public partial class MainWindow : Window
{
UserViewModel userViewModel = new UserViewModel();
UserService userService = new UserService();
public MainWindow()
{
InitializeComponent();
DataContext = userViewModel;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
userService.CheckUserExist();
}
Model:
public string Login { get; set; }
ViewModel:
public class UserViewModel : INotifyPropertyChanged
{
private string _login;
public string Login
{
get { return _login; }
set
{
_login = value;
OnPropertyChange("Login");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChange(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Service:
public string Login { get; set; }
public void CheckUserExist()
{
using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain))
{
var user = UserPrincipal.FindByIdentity(principalContext, Login);
if (user == null)
{ UserMessageText = "xx"; }
{
}
}
}
Why Login in method CheckUserExist() is always null when i start it?
I tried with UpdateSourceTrigger=LostFocus and RaisePropertyChanged();
From method data are correctly sent to VM i View.
The value is always null because you never set it. Also when following the MVVM pattern, your view is not allowed to have a dependency to the model or the UserService to be specific.
It's the responsibility of the view model to pass the value from UserViewModel.Login to UserService.Login:
MainWindow.xaml.cs
public partial class MainWindow : Window
{
private UserViewModel userViewModel = new UserViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = this.userViewModel;
}
}
MainWindow.xaml
<StackPanel>
<TextBox Text="{Binding Login}"/>
<Button Content="Submit" Command="{Binding SubmitLoginDataCommand}"/>
</StackPanel>
UserViewModel.cs
public class UserViewModel
{
public void SubmitLoginData(object loginData)
{
this.userService.CheckUserExist(this.Login);
}
public ICommand SubmitLoginDataCommand => new RelayCommand(SubmitLoginData, param => true);
public string Login { get; set; }
private UserService userService { get; set; }
}
UserService.cs
public void CheckUserExist(string login)
{
using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain))
{
var user = UserPrincipal.FindByIdentity(principalContext, login);
if (user == null)
{
this.UserMessageText = "xx";
}
}
}
RelayCommand.cs
Implementation taken from Microsoft Docs: Relaying Command Logic
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute) : this(execute, null) { }
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
this._execute = execute; this._canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return this._canExecute == null ? true : this._canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter) { this._execute(parameter); }
#endregion // ICommand Members
}
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; }
}
}
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();}
}
}
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);
}
}