Bind event to ViewModel - c#

I am using WPF and PRISM framework for my application. The pattern I am using is MVVM (Model - View - ViewModel) and I am trying to bring the MouseLeftButtonUp event from the code-behind in the View to the ViewModel (so the event will be according the MVVM rules). For now I have this:
View.xaml:
<DataGrid x:Name="employeeGrid" Height="250" Margin="25,0,10,0" ItemsSource="{Binding DetacheringenEmployeesModel}" IsReadOnly="True" ColumnHeaderStyle="{DynamicResource CustomColumnHeader}" AutoGenerateColumns="False" RowHeight="30">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding EmployeeGrid_MouseLeftButtonUp}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
View.xaml.cs (code-behind):
public partial class UC1001_DashBoardConsultants_View
{
public UC1001_DashBoardConsultants_View(UC1001_DashboardConsultantViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}
ViewModel.cs:
public void EmployeeGrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
// insert logic here
}
The main idea is, when I click on a cell in the DataGrid, the event will fire. I first tried it in the code behind, and it worked. I got so far with the EventTriggers, but when I debug and click on a cell, my debugger doesn't come into the method.
Does anyone have an idea how to fix this? Thanks in advance!
PS: Does it also work with the (object sender) parameter when I do it like that? Because I need the DataGrid in my ViewModel to get the ActiveCell I just clicked on.
EDIT:
The event-binding worked with the Command!
I have this in my DataGrid:
<DataGridTextColumn Header="Okt" Width="*" x:Name="test" >
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Tag" Value="{Binding Months[9].AgreementID}"/>
How can I bind the Tag property to the ViewModel? I know it's already bound from the ViewModel, but as you can see the value comes from an Array/List and per column the value is different.

InvokeCommandAction requires the ICommand to be bound not an event handler as you've bound (EmployeeGrid_MouseLeftButtonUp).
So you can introduce a command in ViewModel and bind to it:
View Model:
public ICommand SomeActionCommand { get; set; }
XAML:
<i:InvokeCommandAction Command="{Binding SomeActionCommand}" />

Related

How can I bind a CommandParameter with a child UserControl's child element?

I have the following xaml view:
<UserControl x:Class="MyViews.PersonView"
xmlns:views="clr-namespace:MyViews"
[...]
>
[...]
<dxb:BarManager x:Name="MainBarManager">
<dxb:BarManager.Items>
<dxb:BarButtonItem x:Name="bbiPrint"
Content="{Binding Print, Source={StaticResource CommonResources}}"
Command="{Binding PrintPersonsCommand}"
CommandParameter="{Binding PersonsCardView, ElementName=CardUserControl}"
/>
</dxb:BarManager.Items>
<Grid>
<Grid.RowDefinitions>
[...]
</Grid.RowDefinitions>
<views:CardView x:Name="CardUserControl" Grid.Row="2"/>
</Grid>
[...]
</UserControl>
The CardView is defined as follows:
<UserControl x:Class="MyViews.CardView"
[...]>
[...]
<dxg:GridControl ItemsSource="{Binding Persons}" SelectedItems="{Binding SelectedPersons}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" SelectionMode="MultipleRow">
[...]
<dxg:GridControl.View>
<dxg:CardView x:Name="PersonsCardView"
[...]
CardTemplate="{StaticResource DisplayCardTemplate}"
PrintCardViewItemTemplate="{StaticResource PrintCardTemplate}"/>
</dxg:GridControl.View>
[...]
</dxg:GridControl>
</UserControl>
The PrintPersonsCommand is defined as follows in my ViewModel:
public class PersonViewModel
{
public PersonViewModel(...)
{
[...]
PrintPersonsCommand = new Prism.Commands.DelegateCommand<DataViewBase>(PrintPersons, CanPrintPersons);
}
public Prism.Commands.DelegateCommand<DataViewBase> PrintPersonsCommand { get; private set; }
private void PrintPersons(DataViewBase view)
{
_printService.ShowGridViewPrintPreview(view);
}
private bool CanPrintPersons(DataViewBase view)
{
return true;
}
}
Now, when I click the Print button, the above PrintPersons method is always fed with null. How do I pass CardUserControl.PersonsCardView in my MyViews.PersonView xaml above, how do I pass that PersonCardView to my command? In other words, how do I fix
CommandParameter="{Binding PersonsCardView, ElementName=CardUserControl}"
to make it work?
Currently, the only solution I've found to this problem is to replace the Command and CommandParameter with
ItemClick="OnPrintBtnClick"
and then in the PersonView's code-behind file to do:
private void OnPrintBtnClick(object sender, ItemClickEventArgs e)
{
var ctxt = DataContext as PersonViewModel;
ctxt.PrintPersonsCommand.Execute(CardUserControl.PersonsCardView);
}
That works but I can't believe there is no other way. I'm not happy with that solution because I don't have the benefits of using the Command any more, like e.g. the automatic evaluation of the Command's CanExecute method. I could also put the CardView's xaml code in the PersonView.xaml but I like my controls to be in separate files because I have the feeling it's more structured and each user control has its own responsibilities which can nicely be split into separate files. Also, that solution binds my view to my view model too tightly.
Can someone help me out please?
Without changing your existing view and viewmodel hierarchy, I was able to pass the GridControl.View to the PersonViewModel using the Tag property
You can assign the CardView to the Tag property at the bottom of your CardView UserControl, and then access this Tag as CommandParameter.
CardView UserControl
<UserControl x:Class="MyViews.CardView"
[...]>
[...]
<dxg:GridControl ItemsSource="{Binding Persons}" SelectedItems="{Binding SelectedPersons}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" SelectionMode="MultipleRow">
[...]
<dxg:GridControl.View>
<dxg:CardView x:Name="PersonsCardView"
[...]
CardTemplate="{StaticResource DisplayCardTemplate}"
PrintCardViewItemTemplate="{StaticResource PrintCardTemplate}"/>
</dxg:GridControl.View>
[...]
</dxg:GridControl>
<UserControl.Tag>
<Binding ElementName="PersonsCardView"/>
</UserControl.Tag>
</UserControl>
Print Button Xaml:
<dxb:BarButtonItem x:Name="bbiPrint"
Content="{Binding Print, Source={StaticResource CommonResources}}"
Command="{Binding PrintPersonsCommand}"
CommandParameter="{Binding ElementName=CardUserControl, Path=Tag}"
/>
Based on the valuable input of Insane, I came up with the following two cleaner fixes:
Code-behind solution
In the PersonView, use the ItemClick event handler on the Print button:
<dxb:BarButtonItem x:Name="bbiPrint"
Content="{Binding Print, Source={StaticResource CommonResources}}"
ItemClick="OnPrintBtnClick"/>
Adapt the corresponding code-behind file like this:
public partial class PersonView : UserControl
{
readonly IPrintService _printService;
public PersonView(IPrintService printService)
{
_printService = printService;
InitializeComponent();
}
private void OnPrintBtnClick(object sender, ItemClickEventArgs e)
{
_printService.ShowGridViewPrintPreview(CardUserControl.PersonsCardView);
}
}
Because I want to gray-out the Print button when there is no selection, I still need to add some code to make that happen. I can get it by
1. updating the button code to
<dxb:BarButtonItem x:Name="bbiPrint"
Content="{Binding Print, Source={StaticResource CommonResources}}"
ItemClick="OnPrintBtnClick" IsEnabled="{Binding CanPrintPersons}"/>
refreshing the CanPrintPersons property in the PersonViewModel upon Persons selection change
That's it.
CardViewModel solution
In that solution, we have a PersonView with its underlying PersonViewModel and a CardView with its underlying CardViewModel. I will not describe that solution with all the details as it is overkill in my situation but for the sake of completeness, I'll give the main points. Upon clicking the Print button on the PersonView, the PersonViewModel's PrintCommand is called. That command emits a Print event to the CardViewModel which in turn calls its own PrintCommand. That latter command calls
_printService.ShowGridViewPrintPreview(View);
where the View is a CardViewModel's property that is set upon CardView loading with e.g.
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Loaded" Command="{Binding ViewLoadedCommand}" CommandParameter="{Binding ElementName=PersonsCardView}" />
</dxmvvm:Interaction.Behaviors>
Because I have two child views I want to print, I'd need to add a view model for each one of those. In addition, those two view models plus the PersonViewModel need access to the list of Persons to be printed. In particular, they need a shared access to the same data, so that they are synchronized. A simple way to do that is explained here and is totally doable. But I think it is not worth the trouble for the simple use case I have as it adds more complexity than necessary.

How to bind XAML Command to View -or- Update DataGrid item(s) on modification without INotifyPropertyChanged

I have a WPF DataGrid in a Window with associated View(*.xaml.cs) and ViewModel that is successfully executing a bunch of functionality. However, functions that modify items instead of altering the collection do not update until a sort, resize, etc.
I've found a bunch of search results suggesting the solution is to make the item type implement INotifyPropertyChanged and add/subtract event handlers as appropriate for every item in the collection. I tried for a bit using those examples without success, but frankly it doesn't seem like a great option.
The item type is declared elsewhere in the app and is sharing the object instances with other modules, so I would like not to modify that class. It also seems like a poor design to tie the implementation of the DataGrid's ItemsSource to the item type within; the list container is already an ObservableCollection invoking OnPropertyChanged as needed already, so why should that not be sufficient?
I'm able to update via DataGrid.Items.Refresh() - which unfortunately does not seem to have an overload for specific items/properties instead of updating the entire list, but that's a minor issue - but only my View has a reference to the DataGrid itself (per MVVM), whereas the Command binding is in the ViewModel.
I would actually like to put those Command bindings in the View, and I don't understand why convention is to put those in the VM and thereby bypass the View during a UI event. For example, to delete items I can select them and either press Delete (KeyUp handler is in the View, which then passes selected items as a list to the VM) or select Delete in the context menu (Binding is to an ICommand in the VM, which routes to the same function invoked by the View). Why would it not be more desirable to bind both to the View's event handler (or two handlers both in the View)?
I've seen some results that use a RelativeSource for the Command binding to an ancestor of type UserControl...I've tried with type Window to try to bind to the View's method for naught. As of now my best option is to put a delegate event RefreshListItems on the VM and subscribe to it from the view with a function that invokes DataGrid.Items.Refresh().
This is workable, but in the interest of edification I wondered if anyone could tell me how to bind Command properties to the View (a Window) instead of the ViewModel, and/or how to notify the control bound to my ObservableCollection to refresh either specific or all items from the ViewModel without implementing the INotifyPropertyChanged scheme on every list item?
Edit per mm8's suggestion:
I tried your code for the ICommand in my view, but I get this error:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=SetService; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Command' (type 'ICommand')
That's with each of these attempts, with and without CommandParameter, bound to an ICommand of type either RelayCommand or DelegateCommand:
<MenuItem Header="Set Service" Command="{Binding SetService, RelativeSource={RelativeSource AncestorType=Window}}"/>
<MenuItem Header="Set Service" Command="{Binding SetService, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
<MenuItem Header="Set Service" Command="{Binding SetService, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
.xaml:
<Window>
…
<DataGrid x:Name="TheGrid" ItemsSource="{Binding Source={StaticResource MessageItems}}" KeyUp="MessageList_KeyUp" AutoGenerateColumns="False" IsReadOnly="True" ColumnWidth="Auto">
…
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Set Service" Command="{Binding SetService, RelativeSource={RelativeSource AncestorType=Window}}"/>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
…
</Window>
.xaml.cs:
public partial class TheGridView : Window
{
TheGridViewModel _viewModel;
public ICommand SetService;
[ImportingConstructor]
public TheGridView(TheGridViewModel vm)
{
DataContext = _viewModel = vm;
vm.RefreshListItems += () => TheGrid.Items.Refresh();
InitializeComponent();
Closing += Window_Closing;
SetService = new RelayCommand(SetSvc);
}
private void SetSvc(object selectedItem)
{
// Doesn't get here
}
}
This is workable, but in the interest of edification I wondered if anyone could tell me how to bind Command properties to the View (a Window) instead of the ViewModel?
There is nothing that stops you from defining ICommand properties in the code-behind of the view and bind to them like this (assuming your view is a Window):
Command="{Binding YourCommandProperty, RelativeSource={RelativeSource AncestorType=Window}}"
Edit:
A ContextMenu resides in its own visual tree but you should be able to bind to the parent window through the Tag property of the DataGrid, something like this:
<DataGrid x:Name="TheGrid" ItemsSource="{Binding Source={StaticResource MessageItems}}" KeyUp="MessageList_KeyUp" AutoGenerateColumns="False" IsReadOnly="True" ColumnWidth="Auto">
<DataGrid.Tag>
<Binding Path="." RelativeSource="{RelativeSource AncestorType=Window}" />
</DataGrid.Tag>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Set Service" Command="{Binding PlacementTarget.Tag.SetService, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
...and/or how to notify the control bound to my ObservableCollection to refresh either specific or all items from the ViewModel without implementing the INotifyPropertyChanged scheme on every list item?
You can't do this unless you refresh the entire control (for example using DataGrid.Items.Refresh()). That's why you should implement INotifyPropertyChanged.
If you currently bind to some class that is shared across several modules and you don't want to modify this class, you could create a new client-specifc wrapper class that does implement INotifyPropertyChanged and bind to this one instead of binding to the common class, e.g.:
public class Wrapper : INotifyPropertyChanged
{
private readonly SharedModel _model;
public Wrapper(SharedModel model)
{
_model = model;
}
private string _property;
public string MyProperty
{
get { return _property; }
set { _property = value; OnPropertyChanged(); }
}
//...
public event PropertyChangedEventHandler PropertyChanged;
}

Unable to focus ListView

Situation: In MVVM pattern, I have some inputbindings on a listview which work only when the listview is focused. However, whenever user clicks, the listview goes out of focus and user is unable to execute the inputbindings.
Problem: I want to bring the focus on the listview (on button click) in a way that the inputbindings work.
What I tried:
I tried using attached property IsFocused (where I focus using UIElement.Focus() and/or Keyboard.Focus()) and binding it to a bool variable in the ViewModel which I would set using an ICommand.
I also tried a separate example where I can use the System.Windows.Input.Keyboard.Focus(item) method in the code behind (I mean the .xaml.cs file with the same name) to focus the listview and it works! But, I don't know how to implement the similar thing in a ViewModel which is connected using a d:DesignInstance attribute.
I believe that the mouseclick event is bubbled up and handled somewhere else which causes the list to unfocus as soon as I click it. Like, if I find a way to set the event as handled that will help, but again I don't know how to do that in a viewmodel. Here is my attached property :
FocusExtension.cs
public static class FocusExtension {
public static bool GetIsFocused(DependencyObject obj) {
return (bool)obj.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(DependencyObject obj, bool value) {
obj.SetValue(IsFocusedProperty, value);
}
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached(
"IsFocused", typeof(bool), typeof(FocusExtension),
new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
private static void OnIsFocusedPropertyChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e) {
var uie = (UIElement)d;
if ((bool)e.NewValue) {
uie.Focus();
}
}
}
XAML File:
<ListView
x:Name="lv"
Grid.Column="2" Margin="2" MinWidth="250" Height="400" ToolTip="the List"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding ListBindingInVM}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="False"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropHandler="{Binding }"
behaviour:ListViewAutoScroll.AutoScrollToEnd="True"
ScrollViewer.VerticalScrollBarVisibility="Visible"
>
<ListView.Style>
<Style TargetType="ListView" >
<Setter Property="ViewModels:FocusExtension.IsFocused" Value="{Binding ListFocused, Mode=TwoWay}"></Setter>
<!--The one below is not clean, but worked. However, list goes out of focus on click. -->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ViewModels:FocusExtension.IsFocused" Value="True"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Style>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<!--This command sets the ListFocused to true-->
<i:InvokeCommandAction Command="{Binding BringListToFocus }"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.InputBindings>
<!-- Bindings that don't work when list is not focused-->
<KeyBinding Modifiers="Control" Key="C" Command="{Binding CopyCommand}"/>
<KeyBinding Modifiers="Control" Key="V" Command="{Binding PasteCommand}"/>
</ListView.InputBindings>
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Copy" Command= "{Binding CopyCommand}"></MenuItem>
<MenuItem Header="Paste" Command= "{Binding PasteCommand}"></MenuItem>
</ContextMenu>
</ListView.ContextMenu>
The focus behavior that you describe is easily implemented from the codebehind, and doing so does not violate the MVVM pattern. Consider Josh Smith's post, below:
https://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090097
The use of a ViewModel here makes it much easier to create a view that
can display a Customer object and allow for things like an
"unselected" state of a Boolean property. It also provides the ability
to easily tell the customer to save its state. If the view were bound
directly to a Customer object, the view would require a lot of code to
make this work properly. In a well-designed MVVM architecture, the
codebehind for most Views should be empty, or, at most, only contain
code that manipulates the controls and resources contained within that
view. Sometimes it is also necessary to write code in a View's
codebehind that interacts with a ViewModel object, such as hooking an
event or calling a method that would otherwise be very difficult to
invoke from the ViewModel itself.

Binding Command to Viewmodel with ItemsSource from a StaticResource

I am trying to add an ItemsSource to a MenuItem while keeping the Command bound to my ViewModel (my Window's DataContext). So far, I haven't figured out a way to make it work. Before the ItemsSource is added, the binding is fine. The collection that I am trying to bind comes from a StaticResource. Can anybody help me out with this?
<MenuItem Command="{Binding OpenTeamPage}"
DisplayMemberPath="Name"
Header="Teams"
ItemsSource="{Binding Teams,
Source={StaticResource Container}}" />
I have tried using this and variations of it with no luck:
Command="{Binding OpenTeamPage,
RelativeSource={RelativeSource AncestorType=Window},
Mode=Default}"
If anybody could tell me how to use this ItemsSource while still binding my Command to my ViewModel, I would greatly appreciate it. I suppose I could put the Command in my Team model, but I would like to avoid that if possible.
EDIT : To clarify my problem, with the ItemsSource in place, the command in the ViewModel doesn't fire at all. Without the ItemsSource, the command fires. I would like to be able to have the ItemsSource and still be able to fire the command.
EDIT:
public class GameContainer
{
static GameContainer()
{
Teams = new ObservableCollection<Team>();
}
public static ObservableCollection<Team> Teams { get; set; } 
}
In App.xaml:
<data:GameContainer x:Key="Container" />
The collection is populated when the program is started.
My goal once I get this working is to pass the selected team to the Viewmodel, hopefully via CommandParameter, and display info regarding the selected team.
EDIT: I was mistaken in my original post. A bound collection coming from the Viewmodel does not work either.
This is the behaviour of MenuItem, Item having Child MenuItem won't fire Command and it also should not as it does not make sense. But if you still want to fire a command on Parent Item click,there are two options
You can use Interactivity Triggers on your MenuItem to call command on MouseDown event like
<MenuItem
DisplayMemberPath="Name"
Header="Teams"
ItemsSource="{Binding Teams,
Source={StaticResource Container}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<cmd:EventToCommand Command="{Binding OpenTeamPage}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
you can define a Attached Property for command and define the MenuItem MouseDown behaviour like
public static class MouseCommandBehavior
{
public static readonly DependencyProperty MouseDownCommandProperty =
DependencyProperty.RegisterAttached("MouseDownCommand",
typeof(ICommand),
typeof(MouseCommandBehavior),
new FrameworkPropertyMetadata(null, (obj, e) => OnMouseCommandChanged(obj, (ICommand)e.NewValue, false)));
public static ICommand GetMouseDownCommand(DependencyObject d)
{
return (ICommand)d.GetValue(MouseDownCommandProperty);
}
public static void SetMouseDownCommand(DependencyObject d, ICommand value)
{
d.SetValue(MouseDownCommandProperty, value);
}
private static void OnMouseCommandChanged(DependencyObject d, ICommand command)
{
if (command == null) return;
var element = (FrameworkElement)d;
element.PreviewMouseDown += (obj, e) => command.Execute(null);
}
}
}
and you can set this Property value on your menuItem
<MenuItem local:MouseCommandBehavior.MouseDownCommand="{Binding OpenTeamPage}"
DisplayMemberPath="Name"
Header="Teams"
ItemsSource="{Binding Teams,
Source={StaticResource Container}}">
MenuItem will not execute its command if it's not a leaf node. Only menu items that are leafs (items with no children) are executing a command.
This is probably done due to convention - when you click an items that has children you get the children shown immediately, otherwise there's a delay from mouse hover till children shown.
Although it's probably a bad idea (from UX point of view) to have command on a parent, it's possible:
<MenuItem DisplayMemberPath="Name"
Header="{Binding OpenTeamPage}"
ItemsSource="{Binding Teams, Source={StaticResource Container}}" >
<MenuItem.HeaderTemplate>
<DataTemplate>
<!--Probably need to make this button transparent-->
<Button Content="Teams"
Command="{Binding }"/>
</DataTemplate>
</MenuItem.HeaderTemplate>
<!--This style is for the children to fire the same command as the parent-->
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MenuItem}}, Path=Header}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
Depending upon your design, you'd might need to style the button to be transparent.

CheckBox [Inside ListBox ItemTemplate] Checked Event is not triggering

This is my xaml
<ListBox x:Name="HistoryList"
ItemsSource="{Binding HistoryCollection}"
>
<ListBox.ItemTemplate >
</DataTemplate>
<CheckBox x:Name="UpCheckBox" Height="50" Width="50" >
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="Checked">
<interactivity:InvokeCommandAction Command="{Binding UpCheckedCommad}" CommandParameter="{Binding ElementName=UpCheckBox}"></interactivity:InvokeCommandAction>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate >
</ListBox >
In ViewModel I have used GalasoftMVVM Command Binding
public ICommand UpCheckedCommad
{
get { return new RelayCommand<Object>(x => { PerformUpforTracks(x); }); }
}
void PerformUpforTracks(object x)
{
//TODO
}
I used a CheckBox inside a ListBox ItemTemplate.But am not getting the Checked Event of CheckBox in the ViewModel .
I wanted to get the Checked Event from my ViewModel.Can anyone have any idea to resolve this issue?
Each instance of your ListBox.ItemTemplate is automatically given "the current item in the collection" as its DataContext. In your case, that is each individual item in the HistoryCollection. In your example, the EventTrigger is searching for the "ThumbsUpCheckedCommad" inside your current instance of the HistoryItem.
In order to force the EventTrigger to search in your desired ViewModel, you need to specify the "Source" property of your command binding. I suggest using the RelativeSource syntax, to search up the tree for the last Control to have your ViewModel as its DataContext.
It would look something like this.
{Binding Path=ThumbsUpCheckedCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}
I got it By Binding Command by this way
Command="{Binding Path=DataContext.UpCheckedCommad,
ElementName=HistoryList}"

Categories