Please find the code used for simple binding.
Xaml code:
Button Command="{Binding BoldCommand}"
C# code:
public partial class MainWindow : RibbonWindow
{
public BoldCommand BoldCommand
{
get;
set;
}
public MainWindow()
{
InitializeComponent();
BoldCommand = new BoldCommand();
DataContext = BoldCommand;
}
}
public class BoldCommand : ICommand
{
public BoldCommand()
{
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
}
}
The problem is that your BoldCommand in your DataContext does not have a BoldCommand property.
The major problem you are going to have is that you have conjoined your View and ViewModel. Replace your MainWindow code with the following and it should work.
public partial class MainWindow : RibbonWindow
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
public class MainViewModel
{
public MainViewModel()
{
BoldCommand = new BoldCommand();
}
public BoldCommand BoldCommand { get; set; }
}
Related
for my app, I've created a popup- <Window> that is bound to a ViewModel.
The view model of the popup:
public class GeneratorSelectionViewModel : BaseViewModel
{
private Window mWindow;
public ICommand SelectedCommand { get; set; }
public GeneratorListItem SelectedItem { get; set; }
public GeneratorSelectionViewModel(Window window)
{
mWindow = window;
SelectedCommand = new RelayCommand(GeneratorSelected);
}
private void GeneratorSelected(object parameter)
{
if (SelectedItem != null)
{
mWindow.DialogResult = true;
}
}
}
...that is bound to this popupwindow (here the codebehind):
public partial class GeneratorSelectionPopup : Window
{
public GeneratorSelectionPopup()
{
InitializeComponent();
this.DataContext = new GeneratorSelectionViewModel(this);
}
}
In that window, I have a listbox, where SelectedItem is bound to SelectedItem-property of the VM.
I call this Popup the following way:
GeneratorSelectionPopup SelectionPopup = new GeneratorSelectionPopup();
SelectionPopup.ShowDialog();
Now my question...
How can I transfer that public property SelectedItem from the popups viewmodel to the MainWindow?
`SelectionPopup.SelectedItems` isn't available.
Cast the DataContext of the window:
GeneratorSelectionPopup SelectionPopup = new GeneratorSelectionPopup();
SelectionPopup.ShowDialog();
var selectedItem = (SelectionPopup.DataContext as GeneratorSelectionViewModel).SelectedItem;
You could use an event handler
public partial class GeneratorSelectionPopup : Window
{
public event EventHandler<MyEventArgs> ButtonOkClicked;
public GeneratorSelectionViewModel ViewModel;
public GeneratorSelectionPopup()
{
InitializeComponent();
ViewModel = new GeneratorSelectionViewModel(this);
this.DataContext = ViewModel
}
private void HandleOkButtonClick(object sender, RoutedEventArgs e)
{
ButtonOkClicked?.Invoke(this, new MyEventArgs
{
SelectedItem = this.ViewModel.SelectedItem
});
Window.GetWindow(this).Close();
}
}
public class MyEventArgs: EventArgs
{
public GeneratorListItem SelectedItem { get; set; }
}
And in the mainwindow cs:
GeneratorSelectionPopup SelectionPopup = new GeneratorSelectionPopup();
SelectionPopup.ButtonOkClicked += OnButtonOkClicked;
SelectionPopup.ShowDialog();
private void OnButtonOkClicked(object sender, MyEventArgs e)
{
}
So i have Page with Button and ListView.
Via this Button the user select files that i want to add into my ListView
<Page.Resources>
<vm:ViewModelBase x:Key="ViewModelBase"/>
</Page.Resources>
<Button Command="{Binding AddFilesCommand, Source={StaticResource ViewModelBase}}"/>
<ListView ItemsSource="{Binding Files}"/>
My ViewModel:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<FileBase> _files;
public AddFilesCommand AddFilesCommand { get; set; }
public ViewModelBase()
{
_files = new ObservableCollection<FileBase>();
AddFilesCommand = new AddFilesCommand(this);
}
public void AddFile()
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Title = "Please Select File(s)",
Multiselect = true
};
if (openFileDialog.ShowDialog() == true)
{
string[] files = openFileDialog.FileNames;
if (files.Length > 0)
AddFile(files);
}
}
public void AddFile(string[] files)
{
// Here i am add all my files into my Files collection
}
public ObservableCollection<FileBase> Files
{
get { return _files; }
set
{
_files= value;
NotifyPropertyChanged();
}
}
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
AddFilesCommand
public class AddFilesCommand : ICommand
{
public event EventHandler CanExecuteChanged;
public bool canExecute { get; set; }
public ViewModelBase ViewModel { get; set; }
public AddFilesCommand(ViewModelBase viewModel)
{
canExecute = true;
ViewModel = viewModel;
}
public bool CanExecute(object parameter)
{
return canExecute;
}
public void Execute(object parameter)
{
ViewModel.AddFile();
}
}
Now this works fine and i can see the all the files that the user select are inside my Files collection but i cannot see this files inside my ListView
I would like that my UIElement control acts like a LinkButton in ASP.Net when clicked, and sends an CommandArgument on MouseLeftButtonUp. I suppose I need to make a custom event for this, so I created a OnCommand event like this:
public delegate void OnCommand(object sender, CommandEventArgs e);
public class CommandEventArgs : EventArgs
{
public string CommandArgument { get; set; }
}
How can I add this event to MouseLeftButtonUp on my UIElement, and also pass the CommandArgument? Or is there another way to accomplish the effect of a LinkButton?
I didnt figure out a solution with custom events, so I made a UserControl instead, with a CommandArgument and CommandName properties.
public partial class LinkButton : UserControl
{
public string CommandArgument { get; set; }
public string CommandName { get; set; }
public LinkButton()
{
InitializeComponent();
CommandArgument = String.Empty;
CommandName = String.Empty;
}
public void AddElemnent(UIElement obj)
{
LayoutRoot.Children.Add(obj);
}
}
I have the Xaml which should basically bind a set of ContextualButtons for a selected tab's viewmodel to the ItemsSource property of the ToolBar. For some reason, this binding is not actually occuring unless I use Snoop to inspect the element manually...It seems that the act of snooping the element is somehow requerying the binding somehow.
Does anyone know what I might be doing wrong here? This behavior is the same if I use a Listbox as well, so I know it is something that I am doing incorrectly...but I am not sure what.
SelectedView is a bound property to the selected view from a Xam Tab control.
XAML
<ToolBar DataContext="{Binding SelectedView.ViewModel}"
ItemsSource="{Binding ContextualButtons}" >
<ToolBar.ItemTemplate>
<DataTemplate>
<!-- <Button ToolTip="{Binding Name}"-->
<!-- Command="{Binding Command}">-->
<!-- <Button.Content>-->
<!-- <Image Width="32" Height="32" Source="{Binding ImageSource}"/>-->
<!-- </Button.Content>-->
<!-- </Button>-->
<Button Content="{Binding Name}"/>
</DataTemplate>
</ToolBar.ItemTemplate>
</ToolBar>
Code
public class TestViewModel : BaseViewModel, IBulkToolViewModel
{
public TestViewModel()
{
ContextualButtons = new ObservableCollection<IContextualButton>()
{
new ContextualButton("Test Button",
new DelegateCommand<object>(
o_ => Trace.WriteLine("Called Test Button")), String.Empty)
};
}
public string Key { get; set; }
private ObservableCollection<IContextualButton> _contextualButtons;
public ObservableCollection<IContextualButton> ContextualButtons
{
get { return _contextualButtons; }
set
{
if (_contextualButtons == value) return;
_contextualButtons = value;
//OnPropertyChanged("ContextualButtons");
}
}
}
public partial class TestView : UserControl, IBulkToolView
{
public TestView()
{
InitializeComponent();
}
public IBulkToolViewModel ViewModel { get; set; }
}
public class ContextualButton : IContextualButton
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public ICommand Command { get; set; }
public string ImageSource { get; set; }
public ContextualButton(string name_, ICommand command_, string imageSource_)
{
Name = name_;
Command = command_;
ImageSource = imageSource_;
}
}
public class BulkToolShellViewModel : BaseViewModel, IBaseToolShellViewModel, IViewModel
{
private IBulkToolView _selectedView;
public IBulkToolView SelectedView
{
get
{
return _selectedView;
}
set
{
if (_selectedView == value) return;
_selectedView = value;
OnPropertyChanged("SelectedView");
}
}
public ObservableCollection<IBulkToolView> Views { get; set; }
public DelegateCommand<object> AddViewCommand { get; private set; }
public DelegateCommand<object> OpenPortfolioCommand { get; private set; }
public DelegateCommand<object> SavePortfolioCommand { get; private set; }
public DelegateCommand<object> GetHelpCommand { get; private set; }
public BulkToolShellViewModel(ObservableCollection<IBulkToolView> views_)
: this()
{
Views = views_;
}
public BulkToolShellViewModel()
{
Views = new ObservableCollection<IBulkToolView>();
AddViewCommand = new DelegateCommand<object>(o_ => Views.Add(new TestView
{
ViewModel = new TestViewModel()
}));
OpenPortfolioCommand = new DelegateCommand<object>(OpenPortfolio);
SavePortfolioCommand = new DelegateCommand<object>(SavePortfolio);
GetHelpCommand = new DelegateCommand<object>(GetHelp);
}
private void GetHelp(object obj_)
{
}
private void SavePortfolio(object obj_)
{
}
private void OpenPortfolio(object obj_)
{
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged()
{
throw new NotImplementedException();
}
public void RaisePropertyChanged(string propertyName)
{
throw new NotImplementedException();
}
public string this[string columnName]
{
get { throw new NotImplementedException(); }
}
public string Error { get; private set; }
public AsyncContext Async { get; private set; }
public XmlLanguage Language { get; private set; }
public string Key { get; set; }
}
Thanks!
Why does BulkToolShellViewModel have its own PropertyChanged event along with RaisePropertyChanged methods that do nothing? Shouldn't it inherit this functionality from BaseViewModel? Perhaps the UI is attaching to BulkToolShellViewModel.PropertyChanged rather than BaseViewModel.PropertyChanged and is never being notified of changes.
I've got a view
<UserControl x:Class="Modules.NavigationMenu.Views.NavigationMenuView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<StackPanel>
<Button Command="{Binding InspectionCommand}">Inspection</Button>
<Button Command="{Binding HandheldCommand}">Handheld</Button>
</StackPanel>
</UserControl>
and a simple view model - but the commands won't seem to fire - can anyone point me in the right direction please?
public class NavigationMenuViewModel : INavigationMenuViewModel
{
public INavigationMenuView View { get; set; }
public NavigationMenuViewModel(IEventAggregator eventAggregator, INavigationMenuView view)
{
View = view;
HandheldCommand = new DelegateCommand<object>(LaunchHandheld);
InspectionCommand = new DelegateCommand<object>(LaunchInspection);
}
private void LaunchInspection(object obj)
{
MessageBox.Show("Inspection Clicked");
}
private void LaunchHandheld(object obj)
{
MessageBox.Show("Handheld Clicked");
}
public DelegateCommand<object> HandheldCommand { get; set; }
public DelegateCommand<object> InspectionCommand { get; set; }
}
My Module just looks like ...
public class NavigationMenuModule : IModule
{
private readonly IUnityContainer _container;
private readonly IRegionManager _regionManager;
public NavigationMenuModule(IUnityContainer container, IRegionManager regionManager)
{
_container = container;
_regionManager = regionManager;
}
#region Implementation of IModule
public void Initialize()
{
RegisterViewsAndServices();
var viewModel = _container.Resolve<INavigationMenuViewModel>();
_regionManager.Regions[RegionNames.MainMenu].Add(viewModel.View);
}
#endregion
#region Protected Methods
protected void RegisterViewsAndServices()
{
_container.RegisterType<INavigationMenuView, NavigationMenuView>();
_container.RegisterType<INavigationMenuViewModel, NavigationMenuViewModel>();
}
#endregion
}
Are you sure that the command binding is working? If you run the app and look in the debug output panel, do you see any binding warnings? Perhaps the DataContext of your UserControl isn't set to your NavigationMenuViewModel.