I am trying to use EventArgsConverter on my project, based on this post:
(https://github.com/microsoft/XamlBehaviorsWpf/pull/14)
My problem is that I am not sure where b is referring to? Or where can I download a full sample?
The b: is the xmlns reference to xaml behaviors which is now a nuget package
See
https://devblogs.microsoft.com/dotnet/open-sourcing-xaml-behaviors-for-wpf/
As in
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
Working markup and code:
xmlns:b="http://schemas.microsoft.com/xaml/behaviors">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Button>
<b:Interaction.Triggers>
<b:EventTrigger EventName="Click">
<b:InvokeCommandAction Command="{Binding TestCommand}" />
</b:EventTrigger>
</b:Interaction.Triggers>
</Button>
</Grid>
</Window>
Viewmodel:
public class MainWindowViewModel
{
private ICommand _testCommand;
public ICommand TestCommand
{
get
{
if (_testCommand == null)
{
_testCommand = new RelayCommand(
p => true,
p => this.TestMethod());
}
return _testCommand;
}
}
public void TestMethod()
{
MessageBox.Show("It worked !!!");
}
}
When I click the button, the messagebox appears.
Related
I'm not sure if this is possible but I'm looking for a way to bind a button to a generic class that contain all the properties i will need to use. Every button needs a relay command so that would be included but all of our buttons will need to bind visibility and being enabled. Instead of having this group of properties and relay command for every button we will use within the given windows view model I was wondering if there was a way to have the button bind to a class then in our view model we reference a new instance of that class for each button needed and then be just be able to set the properties on that class to the values we need. I hope this makes sense.
There's probably a bunch of different ways to do something like this. I don't know if I'd choose to have a class instance for each button. But here's a rough/quick/dodgy example of a solution.
The main model for the form is providing the button models by way of a list. The individual button models then handle the button bindings.
EDIT: Extended the code a bit. Now includes command bindings. Also shows use of ItemsControl as suggested by #Xavier. Hope it helps.
MainWindow.xaml:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="400">
<StackPanel>
<!-- Known buttons -->
<StackPanel Margin="20">
<Button DataContext="{Binding ButtonModels[0], Mode=OneTime}" Content="{Binding LabelText}" Background="{Binding Colour}" Command="{Binding Command}" CommandParameter="{Binding CommandParameter}" />
<Button DataContext="{Binding ButtonModels[1], Mode=OneTime}" Content="{Binding LabelText}" Background="{Binding Colour}" Command="{Binding Command}" CommandParameter="{Binding CommandParameter}" />
<Button DataContext="{Binding ButtonModels[2], Mode=OneTime}" Content="{Binding LabelText}" Background="{Binding Colour}" Command="{Binding Command}" CommandParameter="{Binding CommandParameter}" />
</StackPanel>
<!-- Dynamic buttons -->
<StackPanel Margin="20">
<ItemsControl ItemsSource="{Binding ButtonModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding LabelText}" Background="{Binding Colour}" Command="{Binding Command}" CommandParameter="{Binding CommandParameter}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</StackPanel>
</Window>
MainWindow.xaml.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new Model();
}
}
public class Model
{
private Random rnd = new Random();
public List<ButtonModel> ButtonModels { get; private set; }
public Model()
{
this.ButtonModels = new List<ButtonModel>();
for (int i = 0; i < 5; i++)
{
this.ButtonModels.Add(new ButtonModel
{
LabelText = "Button " + (i + 1),
Command = new RelayCommand((index) => { this.ChangeColour((int)index); }),
CommandParameter = i
});
}
}
private void ChangeColour(int index)
{
this.ButtonModels[index].Colour = new SolidColorBrush(Color.FromRgb((byte)rnd.Next(50, 256), (byte)rnd.Next(50, 256), (byte)rnd.Next(50, 256)));
}
}
public class ButtonModel : ObservableObject
{
private string _LabelText;
public string LabelText { get => _LabelText; set => this.SetProperty(ref _LabelText, value); }
private Brush _Colour = new SolidColorBrush(Color.FromRgb(205, 205, 205));
public Brush Colour { get => _Colour; set => this.SetProperty(ref _Colour, value); }
private RelayCommand _Command;
public RelayCommand Command { get => _Command; set => this.SetProperty(ref _Command, value); }
private int _CommandParameter;
public int CommandParameter { get => _CommandParameter; set => this.SetProperty(ref _CommandParameter, value); }
}
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (field == null && value == null)
{
return false;
}
if (field == null || !field.Equals(value))
{
field = value;
this.RaisePropertyChangedEvent(propertyName);
return true;
}
return false;
}
protected void RaisePropertyChangedEvent(string propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class RelayCommand : ICommand
{
private Action<object> execute;
private Predicate<object> canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action<object> action, Predicate<object> canExecute = null)
{
this.execute = action;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return this.canExecute == null || this.canExecute(parameter);
}
public void Execute(object parameter)
{
this.execute(parameter);
}
}
}
I have a ShellView using interactivity objects with prism's PopupWindowAction for show my custom settings view. And my ShellViewModel contain InteractionRequest object and a Delegate Command that will fire the user interaction. After user fired interaction, custom settings view (DataFeedManagerView) appear center of ShellView. In My DataFeedManagerView, there is a list of DataFeeds (ListBox control) on the left side and there is datafeed specific settings view (ContentControl with set Region via RegionManager) on the right side. First, i registered all Views with RegisterViewWithRegion. Then what i try to do is activate related object settings view within content control via Region's Activate method. When i try to do like this, i'm receiving an error "can not find region". So we can not use regions inside custom popup window???
PS1: Maybe this is so simple requirement but containing many steps because of that my explanation was a little bit complicated. I hope code will be more descriptive.
PS2: I meet expectations with using simple binding to ContentControl's content property. But i'm worry about what is my mistake and/or right solution for use regions inside custom interaction popup window.
..::Shell::..
<Window x:Class="PrismUnityApp.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:views="clr-namespace:PrismUnityApp.Views"
xmlns:constants="clr-namespace:PrismUnityApp.Constants"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="{Binding Title}" Height="480" Width="640">
<DockPanel LastChildFill="True">
<i:Interaction.Triggers>
<prism:InteractionRequestTrigger SourceObject="{Binding ConfirmationRequest}">
<prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
<prism:PopupWindowAction.WindowContent>
<views:DataFeedManagerView/>
</prism:PopupWindowAction.WindowContent>
</prism:PopupWindowAction>
</prism:InteractionRequestTrigger>
</i:Interaction.Triggers>
<Button Content=" Show Data Feed Manager" Command="{Binding ShowDataFeedManagerCommand}"/>
<ContentControl prism:RegionManager.RegionName="{x:Static constants:WellKnownRegionNames.ContentRegion}" />
</DockPanel>
using System.Windows.Input;
using Prism.Commands;
using Prism.Interactivity.InteractionRequest;
using Prism.Mvvm;
namespace PrismUnityApp.ViewModels
{
public class ShellViewModel : BindableBase
{
private string _title = "Prism Unity Application";
public ICommand ShowDataFeedManagerCommand { get; }
public InteractionRequest<IConfirmation> ConfirmationRequest { get; }
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public ShellViewModel()
{
ConfirmationRequest = new InteractionRequest<IConfirmation>();
ShowDataFeedManagerCommand = new DelegateCommand(ShowDataFeedManager);
}
public void ShowDataFeedManager()
{
ConfirmationRequest.Raise(
new Confirmation {Title = "Data Feed Manager", Content = string.Empty},
confirmation =>
{
});
}
}
}
..::DataFeedManager::..
<UserControl x:Class="PrismUnityApp.Views.DataFeedManagerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:constants="clr-namespace:PrismUnityApp.Constants"
xmlns:prism="http://prismlibrary.com/"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
prism:ViewModelLocator.AutoWireViewModel="True"
Height="240" Width="320">
<DockPanel LastChildFill="True">
<ListBox
SelectedItem="{Binding Current, Mode=OneWay}"
ItemsSource="{Binding DataFeeds}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<prism:InvokeCommandAction
Command="{Binding SelectionChangedCommand}"
CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource Self}}"></prism:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Key}"></TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ContentControl prism:RegionManager.RegionName="{x:Static constants:WellKnownRegionNames.DataFeedRegion}"></ContentControl>
</DockPanel>
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Practices.Unity;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using PrismUnityApp.Constants;
using PrismUnityApp.Interfaces;
namespace PrismUnityApp.ViewModels
{
public class DataFeedManagerViewModel : BindableBase, IDataFeedManagerViewModel
{
private readonly IRegionManager _regionManager;
public IDictionary<string, object> DataFeeds { get; }
public ICommand SelectionChangedCommand { get; }
public DataFeedManagerViewModel(IUnityContainer unityContainer, IRegionManager regionManager)
{
_regionManager = regionManager;
SelectionChangedCommand = new DelegateCommand<SelectionChangedEventArgs>(SelectionChanged);
DataFeeds = new Dictionary<string, object>
{
{WellKnownDataFeedNames.SimulationDataFeed, unityContainer.Resolve<ISimulationDataFeedView>()},
{WellKnownDataFeedNames.BarchartDataFeed, unityContainer.Resolve<IBarchartDataFeedView>()}
};
foreach (var dataFeed in DataFeeds)
_regionManager.RegisterViewWithRegion(WellKnownRegionNames.DataFeedRegion, () => dataFeed.Value);
}
public void SelectionChanged(SelectionChangedEventArgs e)
{
var addedItem = (KeyValuePair<string, object>) e.AddedItems[0];
var region = _regionManager.Regions[WellKnownRegionNames.DataFeedRegion];
region.Activate(addedItem.Value);
}
}
}
..::Bootstrapper::..
using System.Windows;
using Microsoft.Practices.Unity;
using Prism.Unity;
using PrismUnityApp.Interfaces;
using PrismUnityApp.ViewModels;
using PrismUnityApp.Views;
namespace PrismUnityApp
{
class Bootstrapper : UnityBootstrapper
{
#region Overrides of UnityBootstrapper
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<ISimulationDataFeedView, SimulationDataFeedView>();
Container.RegisterType<ISimulationDataFeedViewModel, SimulationDataFeedViewModel>();
Container.RegisterType<IBarchartDataFeedView, BarchartDataFeedView>();
Container.RegisterType<IBarchartDataFeedViewModel, BarchartDataFeedViewModel>();
Container.RegisterType<IDataFeedManagerView, DataFeedManagerView>();
Container.RegisterType<IDataFeedManagerViewModel, DataFeedManagerViewModel>();
}
protected override DependencyObject CreateShell()
{
return Container.Resolve<ShellView>();
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
#endregion
}
}
Probably you need to set the region manager manually, in the popup view's code behind (constructor), like this:
RegionManager.SetRegionName( theNameOfTheContentControlInsideThePopup, WellKnownRegionNames.DataFeedRegion );
RegionManager.SetRegionManager( theNameOfTheContentControlInsideThePopup, theRegionManagerInstanceFromUnity );
You'll have to assign a name to the content control hosting the region and somehow acquire the region manager (ServiceLocator.Current.GetInstance<IRegionManager>()).
To simplify, Criticized for writing a novel w/no code a month ago, I made a quick wpf project (uses MVVM) with 2 buttons on the UI.
When a button is clicked, I need my ViewModel to know which one, to route the Speech Synthesizer to the correct Text to Speak. Thanks 4 any help!!
Simple UI Image
<Window x:Class="Wpf_School_Announce.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:Wpf_School_Announce"
xmlns:vm="clr-namespace:Wpf_School_Announce.ViewModels"
mc:Ignorable="d"
Title="Announcements" Height="236.436" Width="293.218">
<Window.Resources>
<vm:ViewModelBase x:Key="viewModel"/>
</Window.Resources>
<Grid DataContext="{Binding Source=viewModel}">
<StackPanel Margin="0,10">
<Button x:Name="btn1stBell" Content="1st Bell" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75" Margin="0,10"
Command="{Binding ParameterCommand, Source={StaticResource viewModel}}"
CommandParameter="{Binding Command, ElementName=btn1stBell}"/>
<Button x:Name="btnLunchMenu" Content="Lunch Menu" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75" Margin="0,10"
Command="{Binding ParameterCommand, Source={StaticResource viewModel}}"
CommandParameter="{Binding Command, ElementName=LunchMenu}"/>
</StackPanel>
</Grid>
</Window>
namespace Wpf_School_Announce.ViewModels
{
public class ViewModelBase
{
public ParameterCommand ParameterCommand { get; set; }
public ViewModelBase()
{
ParameterCommand = new ParameterCommand(this);
}
public void ParameterMethod(string <Not sure what needs to go here>)
{
Debug.WriteLine("Parameter Comand:{0}", AnnoucementModel);
//Todo: Need to find out which UI button was clicked to direct The Speech Synthesozer to the correct Speech Text.
}
}
}
namespace Wpf_School_Announce.ViewModels.Commands
{
public class ParameterCommand : ICommand
{
public ViewModelBase ViewModel { get; set; }
public ParameterCommand(ViewModelBase viewModel)
{
ViewModel = viewModel;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
ViewModel.ParameterMethod(parameter as String);
}
}
}
It is a bad solution to just have one command on your viewmodel and to bind every button to it. If you have different things to be executed, define different commands. For that you either have to define a separate class with a dedicated Execute metod for each command or you can use something like RelayCommand of MvvmLight, where you can pass delegates upon creation of each command like this
public class ViewModelBase
{
public RelayCommand BellCommand...
public RelayCommand LunchCommand...
public ViewModelBase()
{
this.BellCommand = new RelayCommand(this.ExecuteBell);
this.LunchCommand = new RelayCommand(this.ExecuteLunch);
}
private void ExecuteBell(object Parameter) {...}
private void ExecuteLunch(object Parameter) {...}
}
and in your XAML
<Button Command="{Binding Path=BellCommand}"... />
<Button Command="{Binding Path=LunchCommand}" ... />
This way you have separate places for the individual logic and your viewmodel must not know anything about your ui - which is good.
Hope it helps.
XAML:
<Button CommandParameter="command_name" Command="{Binding OnClick}" Content="Click Me"></Button>
Event.cs:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
private ICommand onClick;
public ICommand OnClick
{
get
{
return onClick ?? (onClick = new RelayCommand(clickSwitch));
}
}
Class.cs:
private async void clickSwitch(System.Object obj)
{
switch (obj.ToString())
{
case "command_name":
//code
break;
}
I am trying to create MDI kind of functionality whereby I want to load a user control corresponding to the button clicked by user and unload the rest. Every button is associated with a userControl
<Button Content="Worker registration"/> //UserControl1
<Button Content="Worker recognition"/> //UserControl2 ...and so on
<Grid x:Name="UserControlManager"/>
Any reason not to use a tabcontrol? Like this
<TabControl>
<TabItem Header="Control A">
<local:ControlA/>
</TabItem>
<TabItem Header="Control B">
<local:UserControlB/>
</TabItem>
</TabControl>
Or bind all items using the ItemsSource
<TabControl ItemsSource="{Binding MyItems}"/>
There are also third party TabControls that's quite nice, like the one devcomponents provides.
If a TabControl does not suffice (tons of issues I know), you could use a IValueConverter that would convert some property to a view. You could use a Mediator and/or ViewModelLocator, I love MVVM Light from Galasoft. They provide everything through nuget, and even sets up everything for you :)
Add a command for your buttons for selecting the content you want to show. And add the xaml for showing the SelectedControl.
Bad mediator / ViewmodelLocator ;) Use I.E. Galasofts instead like in this post
public class ViewModelLocator : INotifyPropertyChanged
{
private UserControl selectedControl;
private ObservableCollection<UserControl> controls = new ObservableCollection<UserControl>();
public UserControl SelectedControl
{
get { return selectedControl; }
set
{
if (Equals(selectedControl, value)) return;
selectedControl = value;
OnPropertyChanged();
}
}
public ObservableCollection<UserControl> Controls
{
get { return controls; }
set
{
if (Equals(controls, value)) return;
controls = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Hope it helps!
Cheers
Stian
You can use DataTemplates to load views depending on what data (viweModel) you set
<Window.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type viewModel:ViewModel1}">
<view:View1 />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:ViewModel2}">
<view:View2 />
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
Then have a ContentControl where your content will show
<Grid >
<ContentControl Content="{Binding MyContent}" />
</Grid
Use an enumBooleanConverter (How to bind RadioButtons to an enum?) to select a enum with radiobuttons
<RadioButton GroupName="Navigation"
IsChecked="{Binding Path=SelectedNavigationEnum,
Converter={StaticResource enumBooleanConverter},
ConverterParameter={x:Static viewModel:NavigationEnum.EnumValue1},
Mode=TwoWay}">Show View1</RadioButton>
<RadioButton GroupName="Navigation"
IsChecked="{Binding Path=SelectedNavigationEnum,
Converter={StaticResource enumBooleanConverter},
ConverterParameter={x:Static viewModel:NavigationEnum.EnumValue2},
Mode=TwoWay}">Show View2</RadioButton>
When the SelectedNavigationEnum property is changed set the MyContent property to the selected viewModel
public NavigationEnum SelectedNavigationEnum
{
...
set
{
...
Navigate(value);
}
}
protected void Navigate(NavigationEnum part)
{
switch (part)
{
case NavigationEnum.EnumValue1:
ShowView1();
break;
case NavigationEnum.EnumValue2:
ShowView2();
...
}
}
private void ShowView1()
{
ViewModel1 viewModel = ObjectFactory.GetInstance<ViewModel1>();
MyContent = viewModel;
}
When you set MyContent the DataTemplate will load View1 and set the viewModel as its DataContext.
I'm using the MVVM Light Toolkit with Silverlight.
On my UserControl I have a ListBox that displays a list of files. Each file has a delete image next to the file name. In the DataTemplate for the listbox I have an image (or can use a button) and a TextBlock.
So I want to capture using the event when the user will clicks on the image(or button with image) to remove the file from the list of files.
But I cannot seem to capture the event. Maybe this is due to having the SelectedItem Event on the listbox?
public class MainViewModel : ViewModelBase
{
#region Properties
public const string SelectedListBoxFilePropertyName = "SelectedUploadFile";
private UploadFile _selectedUploadFile = null;
public UploadFile SelectedUploadFile
{
get
{
return _selectedUploadFile;
}
set
{
if (_selectedUploadFile == value)
return;
_selectedUploadFile = value;
RaisePropertyChanged(SelectedListBoxFilePropertyName);
}
}
public const string UploadFilesPropertyName = "UploadFiles";
private ObservableCollection<UploadFile> _uploadFiles = new ObservableCollection<UploadFile>();
public ObservableCollection<UploadFile> UploadFiles
{
get
{
return _uploadFiles;
}
set
{
if (_uploadFiles == value)
return;
_uploadFiles = value;
RaisePropertyChanged(UploadFilesPropertyName);
}
}
#endregion
public static ICommand BrowseCommand { get; private set; }
public static ICommand DragDropFileCommand { get; private set; }
public static ICommand RemoveCommand { get; private set; }
#region Constructor
public MainViewModel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
UploadFiles = new UploadFileContainer().UploadFiles;
}
else
{
// Code runs "for real"
}
WireUpCommands();
}
#endregion
#region Event Handlers
private void OnBrowseFileCommand()
{
var dialog = new OpenFileDialog();
dialog.ShowDialog();
if (dialog.Files != null)
AddFiles(dialog.Files);
}
private void OnDropFileCommand(DragEventArgs e)
{
var files = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];
AddFiles(files);
}
private void OnRemoveFileCommand()
{
UploadFiles.Remove(_selectedUploadFile);
}
#endregion
#region Private Methods
private void WireUpCommands()
{
BrowseCommand = new RelayCommand(OnBrowseFileCommand);
DragDropFileCommand = new RelayCommand<DragEventArgs>(e => OnDropFileCommand(e));
RemoveCommand = new RelayCommand(OnRemoveFileCommand);
UploadCommand = new RelayCommand(OnClickUploadCommand);
}
#endregion
}
<ListBox Grid.Row="1" Height="214" HorizontalAlignment="Left" AllowDrop="True" Margin="6,26,0,0" Name="UploadFilesListBox" VerticalAlignment="Top" Width="415" ItemsSource="{Binding Path=UploadFiles}" SelectedItem="{Binding Path=SelectedListBoxFile, Mode=TwoWay}" ScrollViewer.VerticalScrollBarVisibility="Auto">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Drop">
<cmd:EventToCommand Command="{Binding DragDropFileCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.Background>
<ImageBrush ImageSource="/FileUploadApplication;component/Resources/dragdrophere.png" Stretch="None" />
</ListBox.Background>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding RemoveCommand}">
<Image Source="/FileUploadApplication;component/Resources/delete.png"/>
</Button>
<Image Source="/FileUploadApplication;component/Resources/delete.png">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding RemoveCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image> <TextBlock Text=" " />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Since your ItemsSource is UploadFiles it's probably sending the event to UploadFile and not the view model the user control is bound to.
Your button is the element of the ItemTemplate. you're binding the listbox ItemsSource to the ObservableCollection. Every Itemtemplate DataContext is no MainViewModel, but UploadFile, which has no RemoveCommand.
I was solving this by adding to every item the parent object using constructor. RemoveCommand was inside the item's ViewModel and insede the remove function i was calling the parent's method to delete the item.
Not sure if that's the best solution but it worked for me.