I have some UserControls
inside of an ItemsControl
.
Each UserControl
(called JobView
in my case) has a ContextMenu
with 1 Item
('Remove').
Now when the Item on the UserControls ContextMenu
is Clicked
I want to remove it from the ItemsControlItemCollection
.
For that I need to get the Item
, the ContextMenu is assigned to.
Currently I am using this:
private void Item_Click(object sender, RoutedEventArgs e)
{
MenuItem item = (MenuItem)sender;
JobView view = null;
FrameworkElement currentObject = item;
while(1 == 1)
{
currentObject = currentObject.Parent as FrameworkElement;
if(currentObject.GetType() == typeof(System.Windows.Controls.Primitives.Popup))
{
view = (currentObject as System.Windows.Controls.Primitives.Popup).PlacementTarget as JobView;
break;
}
}
//Remove from ObservableCollection<JobView>:
JobViews.Remove(view);
}
It is working fine but I am pretty sure that there must me some better solution.
Took me some time to figure that one out but I can't get to a different solution myself.
How can I get the JobView
using the sender
object
or is using sender
completely wrong in this case ?
Binding or setting the ItemsSource of an ItemsControl to an ObservableCollection of UIElements or views is wrong. At least if you care about the MVVM design pattern which is the recommended pattern to use for all XAML based applications.
You should create a class that represents the state of your JobView and bind to an ObservableCollection of such objects, e.g.:
You then use your UserControl (JobView) in the ItemTemplate of the ItemsControl:
With this in place you could then add an ICommand property to the JobView class that binds to a command property of the view model that removes the Job class from the source collection. Please refer to the following sample code.
JobViewModel.cs:
JobView.xaml.cs:
JobView.xaml:
MainWindow.xaml:
You will need to implement the DelegateCommand class yourself or you could use the one available in the Prism MVVM Library: https://github.com/PrismLibrary/Prism/blob/master/Source/Prism/Commands/DelegateCommand.cs
Prism can be installed using NuGet: https://www.nuget.org/packages/Prism.Wpf/.
You can read more about the MVVM pattern here: https://msdn.microsoft.com/en-us/library/hh848246.aspx. I really recommend you to learn it if you are developing XAML applications.