How to move borderless wpf window without code behind file - c#

I'm creating a WPF application with a borderless window. Applying the MVVVM pattern (with help of Caliburn.Micro) I do not have a code behind file but only a XAML file.
In several posts I found following solution:
XAML:
<Window
...
WindowStyle="None" MouseLeftButtonDown="WindowMouseLeftButtonDown"/>
Code behind:
private void WindowMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
Now I'm searching a solution to define this completely in XAML.
Any idea?

The solution I will present is not really advised, but you can put your code behind right in your XAML file like this:
<Window
...
WindowStyle="None" MouseLeftButtonDown="WindowMouseLeftButtonDown"/>
<x:Code>
<![CDATA[
private void WindowMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
]]>
</x:Code>
Check this Codeproject article for more information on this!

I think your best option is a behavior.
http://wpftutorial.net/Behaviors.html

You can download the Microsoft.Windows.Shell dll (Link. You can find another download options with google), which gives you a property of CaptionHeight that enables tou to drag the window from its top part (like a normal window).

You can use an EventCommandTrigger. Check these references:
http://www.danharman.net/2011/08/05/binding-wpf-events-to-mvvm-viewmodel-commands/
http://zamjad.wordpress.com/2011/06/07/convert-event-into-command-in-mvvm-model/

I know that I am a little late to the question, but this is what I have been using for sometime now and it works like a charm.
DashboardViewModel viewModel;
public DashboardView()
{
InitializeComponent();
viewModel = new DashboardViewModel();
viewModel.RequestClose += (s, e) => Application.Current.Dispatcher.Invoke(this.Close);
viewModel.RequestMinimize += (s, e) => Application.Current.Dispatcher.Invoke(() => { this.WindowState = WindowState.Minimized; });
DataContext = viewModel;
}
and something like this in your viewModel
#region Public Event Handlers
public event EventHandler<EventArgs> RequestClose;
public event EventHandler<EventArgs> RequestMinimize;
#endregion
Using the ICommand interface...
#region ICommand Members
public ICommand CloseCommand { get; private set; }
public ICommand MinimizeCommand { get; private set; }
#endregion
Configure the commands...
private void SetupCommands()
{
CloseCommand = new RelayCommand(CloseApplication);
MinimizeCommand = new RelayCommand(MinimizeApplication);
}
Here is the RelayCommand class.
public class RelayCommand : ICommand
{
#region Private Readonly Properties
private readonly Action<object> executeCommand;
private readonly Predicate<object> canExecute;
#endregion
#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.executeCommand = execute;
this.canExecute = canExecute;
}
#endregion
#region Public ICommand Members
public bool CanExecute(object parameter)
{
return canExecute == null ? true : canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
executeCommand(parameter);
}
#endregion
}
And some example methods...
private void MinimizeApplication(object obj)
{
RequestMinimize(this, new EventArgs());
}
private void CloseApplication(object obj)
{
RequestClose(this, new EventArgs());
}
Hope this helps!

Related

Why does an ICommand object have to be public to work properly in WPF?

I am following a course on Pluralsight called "Practical MVVM". In the 4th module of the course, the author was explaining how to use commands and that's when I had this strange issue. I had written almost the same code as it was in the video except for one difference. My local ICommand variable was declared as private instead of public.
Here is what happens when I click the button that has a Binding set to the method EditCoffee() that belongs to EditCommand command:
When ICommand EditCommand is declared as public or internal the method EditCoffee() is executed following the execution of Execute() and CanExecute() in CustomCommand class.
When ICommand EditCommand is declared as private or protected the method EditCoffee() is never executed and does not follow execution of Execute() and CanExecute() in CustomCommand class.
It's worth mentioning that LoadCommands() is triggered on in both scenarios.
CoffeeOverviewViewModel:
using JoeCoffeeStore.StockManagement.App.Services;
using JoeCoffeeStore.StockManagement.App.Utility;
using JoeCoffeeStore.StockManagement.Model;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
namespace JoeCoffeeStore.StockManagement.App.ViewModel
{
public class CoffeeOverviewViewModel : INotifyPropertyChanged
{
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// Commands
private ICommand EditCommand { get; set; }
// Data Service
private CoffeeDataService _coffeeDataService;
// Properties
private ObservableCollection<Coffee> _coffees;
public ObservableCollection<Coffee> Coffees
{
get{ return _coffees; }
set
{
_coffees = value;
OnPropertyChanged();
}
}
private Coffee _selectedCoffee;
public Coffee SelectedCoffee
{
get { return _selectedCoffee; }
set
{
_selectedCoffee = value;
OnPropertyChanged();
}
}
// Constructor
public CoffeeOverviewViewModel()
{
_coffeeDataService = new CoffeeDataService();
LoadData();
LoadCommands();
}
private void LoadCommands()
{
EditCommand = new CustomCommand(EditCoffee, CanEditCoffee);
}
private void EditCoffee(object obj)
{
//TODO
}
private bool CanEditCoffee(object obj)
{
if (SelectedCoffee != null)
return true;
return false;
}
private void LoadData()
{
Coffees = new ObservableCollection<Coffee>(_coffeeDataService.GetAllCoffees());
}
}
}
CustomCommand.cs:
using System;
using System.Windows.Input;
namespace JoeCoffeeStore.StockManagement.App.Utility
{
public class CustomCommand : ICommand
{
private Action<object> _execute;
private Predicate<object> _canExecute;
public CustomCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public bool CanExecute(object parameter)
{
bool b = _canExecute == null ? true : _canExecute(parameter);
return b;
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
}
CoffeeOverviewView.xaml:
<StackPanel Grid.Row="7">
<Button Command="{Binding EditCommand}" Content="Edit coffee"/>
</StackPanel>
Solution structure:
Binding isn't magic. It's code that takes your XAML binding declaration:
<Button Command="{Binding EditCommand}"
and looks for a property of that name, EditCommand, in the DataContext of your class.
Your XAML view is a separate class than your ViewModel, so it makes sense that it can only access public properties on the ViewModel. Even internal properties are out of bounds, because it's the binding code that tries to access it, in the WPF libraries, not your own view code.

Relaycommand ICommand.CanExecute not firing

i have the following problem:
I have a relaycommand with a execute an a canexecute method, but everytime i call raisecanexecutechanged(); it calls raisecanexecutechanged in relaycommand, sets a new delegate for it and then returns back to the view model.
The same setup works in another viewmodel. I checked like 1000 times what's different but i don't find anything.
I would really appreciate if you could help me.
public RelayCommand UpdateAMSCommand { get; private set; }
public AMSSettingsViewModel(IEventAggregator eventAggregator)
{
UpdateAMSCommand = new RelayCommand(OnUpdateAMS, CanUpdateAms);
CustomAMSOffices.ListChanged += listChanged;
CustomAMSContacts.ListChanged += listChanged;
}
private void listChanged(object sender, ListChangedEventArgs e)
{
if (sender != null)
{
if (sender is BindingList<CustomAMSOffice>)
{
BindingList<CustomAMSOffice> temp = (BindingList<CustomAMSOffice>)sender;
if (temp.Count > _amsOfficesItemsCounter)
{
_amsOfficesItemsCounter = temp.Count;
for (int i = 0; i < temp.Count; i++)
{
temp[i].ErrorsChanged += RaiseCanExecuteChanged;
}
}
}
else if (sender is BindingList<CustomAMSContact>)
{
BindingList<CustomAMSContact> temp = (BindingList<CustomAMSContact>)sender;
if (temp.Count > _amsContactsItemsCounter)
{
_amsContactsItemsCounter = temp.Count;
for (int i = 0; i < temp.Count; i++)
{
temp[i].ErrorsChanged += RaiseCanExecuteChanged;
}
}
}
}
UpdateAMSCommand.RaiseCanExecuteChanged();
}
private void RaiseCanExecuteChanged(object sender, DataErrorsChangedEventArgs e)
{
UpdateAMSCommand.RaiseCanExecuteChanged();
}
private bool CanUpdateAms()
{
foreach (var cao in CustomAMSOffices)
{
if (!cao.Check() || cao.HasErrors)
{
return false;
}
}
foreach (var cac in CustomAMSContacts)
{
if (!cac.Check() || cac.HasErrors)
{
return false;
}
}
return true;
}
Edit:
the relaycommand i use: https://github.com/briannoyes/WPFMVVM-StarterCode/blob/master/ZzaDashboard/ZzaDashboard/RelayCommand.cs
Ok, I'm just going to copy paste some code that I have in use, so that you should be able to pop these into your project and use.
First off, the RelayCommand() class. I lifted this code from this msdn page:
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion
#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");
_execute = execute;
_canExecute = canExecute;
}
#endregion
#region ICommand Members
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion
}
Now our ModelView.cs class needs to inherit from INotifyPropertyChangedand will have our RaisePropertyChanged(). Now I usually make just make this a it's own file and have all my ModelViews inherit from it so the code is a little cleaner, but you can do as you please.
Here's how I have it setup though:
BaseViewModel.cs:
public class BaseViewModel : INotifyPropertyChanged
{
internal void RaisePropertyChanged(string prop)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
}
public event PropertyChangedEventHandler PropertyChanged;
// Any other code we want all model views to have
}
Now for our MainViewModel.cs we will just inherit from BaseViewModel, add our event handlers in, and run it!
Example: ServerViewModel.cs
public class ServerViewModel : BaseViewModel
{
public RelayCommand BroadcastMessageCommand { get; set; }
private string _broadcastmessage;
public string broadcastmessage
{
get { return _broadcastmessage; }
set { _broadcastmessage = value; RaisePropertyChanged("broadcastmessage"); }
}
Server server;
public ServerViewModel()
{
server = new Server();
server.run();
BroadcastMessageCommand = new RelayCommand(BroadcastMessage, CanBroadcast);
}
private bool CanBroadcast(object param)
{
if (string.IsNullOrWhiteSpace(broadcastmessage))
return false;
if (!server.running)
return false;
return true;
}
public void BroadcastMessage(object param)
{
server.BroadcastMessage(broadcastmessage);
broadcastmessage = "";
RaisePropertyChanged("broadcastmessage");
}
}
Now anything in our MainView.xaml that is bound with Command="{Binding broadcastmessage}" will update appropriately. In my case I have this bound to a button and the button will be disabled if there message is empty, or if we are not connected to the server.
Hopefully that's enough code example to get you headed in the right direction! Let me know if you have any questions on it.
Let's try simplifying the code as much as we can until we get this working properly, and then we will slowly add code back until we find the code(s) that are causing trouble.
So let's reduce this to it's barebones and see if we have any success. Try this code:
public RelayCommand UpdateAMSCommand { get; private set; }
public AMSSettingsViewModel(IEventAggregator eventAggregator)
{
UpdateAMSCommand = new RelayCommand(OnUpdateAMS, CanUpdateAms);
CustomAMSOffices.ListChanged += listChanged;
CustomAMSContacts.ListChanged += listChanged;
}
private void listChanged(object sender, ListChangedEventArgs e)
{
UpdateAMSCommand.RaiseCanExecuteChanged();
}
private void RaiseCanExecuteChanged(object sender, DataErrorsChangedEventArgs e)
{
UpdateAMSCommand.RaiseCanExecuteChanged();
}
// This will simply flip from true to false every time it is called.
private bool _canupdate = false;
private bool CanUpdateAms()
{
_canupdate = !_canupdate;
return _canupdate;
}
Edit: I don't know why it doesn't work.

Simple explanation of how to use commands with a button click in WPF

I'm a starter and I'm trying to use commands instead of Click="Display".
<Button Content ="Click Me!" Command = "{Binding ClickMeCommand}" />
How would I write the method to use the command? Say I want to display a message like "clicked!" in the console when the button is clicked. I'm looking for the simplest implementation that is easy to understand please. I've tried looking at tutorials but they over complicate things and it is hard for me to understand.
One way would be like this:
Create your ViewModel :
public class MainViewModel
{
public MainViewModel()
{
}
private ICommand clickMeCommand;
public ICommand ClickMeCommand
{
get
{
if (clickMeCommand == null)
clickMeCommand = new RelayCommand(i => this.ClickMe(), null);
return clickMeCommand;
}
}
private void ClickMe()
{
MessageBox.Show("You Clicked Me");
}
}
Or initialize it in the constructor.
First paramater of the Command is the method that will be executed when you click the button you binded your command to. The second parameter is the method that enables/disables the button based on the logic. If you would like the button to be enabled at all times just set:
In your MainWindow code behind set the MainViewModel as the datacontext of your mainwindow.
public partial class MainWindow : Window
{
public MainWindow()
{
MainViewModel vm = new MainViewModel();
InitializeComponent();
this.DataContext = vm;
}
}
And the RelayCommand class(this is just an implementation of the ICommand Interface). You can use other implementation of ICommand if you want.
public class RelayCommand : ICommand
{
readonly Action<object> execute;
readonly Predicate<object> canExecute;
public RelayCommand(Action<object> executeDelegate, Predicate<object> canExecuteDelegate)
{
execute = executeDelegate;
canExecute = canExecuteDelegate;
}
bool ICommand.CanExecute(object parameter)
{
return canExecute == null ? true : canExecute(parameter);
}
event EventHandler ICommand.CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
void ICommand.Execute(object parameter)
{
execute(parameter);
}
}

Wiring up the code behind of the View with some Action in the ViewModel

In a Silverlight app that is written with MVVM I want to enable/disable my view based on some stuff.
In the constructor of the View class in code behind I can say something like this and it disables the form:
public MyForm1View()
{
InitializeComponent();
if(this.DataContext == null)
{
this.IsEnabled = False;
}
}
The issue is when there is no data to load, I am showing a gray overlay screen on top of my form to the user with a link on that gray overlay that says "Create a New Record"....now the problem is that if I disable my form like that above then How can I re-enable it when they click that CreateNewRecord link?
But how can I reenable it again from the view-model? Maybe I should have an Action on my ViewModel and when it's called on the ViewModel, it calls a method that's wired up in the code behind of the View ? But how to code this idea?
I would suggest few things:
simple wrapper for ICommand Interface:
public class DelegateCommand : ICommand
{
private readonly Action execute;
private readonly Func<bool> canExecute;
public DelegateCommand(Action execute, Func<bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (this.canExecute != null)
{
return this.canExecute();
}
else
{
return true;
}
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
execute();
}
public void RaiseExecuteChanged()
{
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, new EventArgs());
}
}
}
ViewModel:
public class ViewModel : INotifyPropertyChanged {
public void ViewModel() {
SwitchCommand = new DelegateCommand(() => this.IsEnabled = true, () => true);
}
public DelegateCommand SwitchCommand {get;set;}
private bool isEnabled;
public bool IsEnabled {
get {
return isEnabled;
}
set {
isEnabled = value;
NotifyPropertyChanged("IsEnabled");
}
// here, InotifyPropertyChanged implementation, dozens of sample available
}
Xaml:
as example:
<Button Command={Binding SwitchCommand} /> bind command to click.
So, what's left is to set ViewModel to View, via view constructor, of IoC if you use it.
hope that help.

ICommand MVVM implementation

So in this particular MVVM implementation I'm doing, I need several commands. I really got tired of implementing the ICommand classes one by one, so I came up with a solution, but I don't know how good it is, so the input of any WPF expert here will be greatly appreciated. And if you could provide a better solution, even better.
What I did is a single ICommand class and two delegates which take an object as a parameter, one delegate is void (for OnExecute), the other bool (for OnCanExecute). So in the constructor of my ICommand (which is called by the ViewModel class) I send the two methods, and on each ICommand method I invoke the delegates' methods.
It works really good, but I'm not sure if this is a bad way to do it, or if there's a better way. Below is the complete code, any input will be greatly appreciated, even negative, but please be constructive.
ViewModel:
public class TestViewModel : DependencyObject
{
public ICommand Command1 { get; set; }
public ICommand Command2 { get; set; }
public ICommand Command3 { get; set; }
public TestViewModel()
{
this.Command1 = new TestCommand(ExecuteCommand1, CanExecuteCommand1);
this.Command2 = new TestCommand(ExecuteCommand2, CanExecuteCommand2);
this.Command3 = new TestCommand(ExecuteCommand3, CanExecuteCommand3);
}
public bool CanExecuteCommand1(object parameter)
{
return true;
}
public void ExecuteCommand1(object parameter)
{
MessageBox.Show("Executing command 1");
}
public bool CanExecuteCommand2(object parameter)
{
return true;
}
public void ExecuteCommand2(object parameter)
{
MessageBox.Show("Executing command 2");
}
public bool CanExecuteCommand3(object parameter)
{
return true;
}
public void ExecuteCommand3(object parameter)
{
MessageBox.Show("Executing command 3");
}
}
ICommand:
public class TestCommand : ICommand
{
public delegate void ICommandOnExecute(object parameter);
public delegate bool ICommandOnCanExecute(object parameter);
private ICommandOnExecute _execute;
private ICommandOnCanExecute _canExecute;
public TestCommand(ICommandOnExecute onExecuteMethod, ICommandOnCanExecute onCanExecuteMethod)
{
_execute = onExecuteMethod;
_canExecute = onCanExecuteMethod;
}
#region ICommand Members
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute.Invoke(parameter);
}
public void Execute(object parameter)
{
_execute.Invoke(parameter);
}
#endregion
}
This is almost identical to how Karl Shifflet demonstrated a RelayCommand, where Execute fires a predetermined Action<T>. A top-notch solution, if you ask me.
public class RelayCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _execute;
public RelayCommand(Predicate<object> canExecute, Action<object> execute)
{
_canExecute = canExecute;
_execute = execute;
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object parameter)
{
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
This could then be used as...
public class MyViewModel
{
private ICommand _doSomething;
public ICommand DoSomethingCommand
{
get
{
if (_doSomething == null)
{
_doSomething = new RelayCommand(
p => this.CanDoSomething,
p => this.DoSomeImportantMethod());
}
return _doSomething;
}
}
}
Read more:
Josh Smith (introducer of RelayCommand): Patterns - WPF Apps With The MVVM Design Pattern
I have written this article about the ICommand interface.
The idea - creating a universal command that takes two delegates: one is called when ICommand.Execute (object param) is invoked, the second checks the status of whether you can execute the command (ICommand.CanExecute (object param)).
Requires the method to switching event CanExecuteChanged. It is called from the user interface elements for switching the state CanExecute() command.
public class ModelCommand : ICommand
{
#region Constructors
public ModelCommand(Action<object> execute)
: this(execute, null) { }
public ModelCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
#endregion
#region ICommand Members
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return _canExecute != null ? _canExecute(parameter) : true;
}
public void Execute(object parameter)
{
if (_execute != null)
_execute(parameter);
}
public void OnCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
#endregion
private readonly Action<object> _execute = null;
private readonly Predicate<object> _canExecute = null;
}
I've just created a little example showing how to implement commands in convention over configuration style. However it requires Reflection.Emit() to be available. The supporting code may seem a little weird but once written it can be used many times.
Teaser:
public class SampleViewModel: BaseViewModelStub
{
public string Name { get; set; }
[UiCommand]
public void HelloWorld()
{
MessageBox.Show("Hello World!");
}
[UiCommand]
public void Print()
{
MessageBox.Show(String.Concat("Hello, ", Name, "!"), "SampleViewModel");
}
public bool CanPrint()
{
return !String.IsNullOrEmpty(Name);
}
}
}
UPDATE: now there seem to exist some libraries like http://www.codeproject.com/Articles/101881/Executing-Command-Logic-in-a-View-Model that solve the problem of ICommand boilerplate code.
#Carlo I really like your implementation of this, but I wanted to share my version and how to use it in my ViewModel
First implement ICommand
public class Command : ICommand
{
public delegate void ICommandOnExecute();
public delegate bool ICommandOnCanExecute();
private ICommandOnExecute _execute;
private ICommandOnCanExecute _canExecute;
public Command(ICommandOnExecute onExecuteMethod, ICommandOnCanExecute onCanExecuteMethod = null)
{
_execute = onExecuteMethod;
_canExecute = onCanExecuteMethod;
}
#region ICommand Members
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute?.Invoke() ?? true;
}
public void Execute(object parameter)
{
_execute?.Invoke();
}
#endregion
}
Notice I have removed the parameter from ICommandOnExecute and ICommandOnCanExecute and added a null to the constructor
Then to use in the ViewModel
public Command CommandToRun_WithCheck
{
get
{
return new Command(() =>
{
// Code to run
}, () =>
{
// Code to check to see if we can run
// Return true or false
});
}
}
public Command CommandToRun_NoCheck
{
get
{
return new Command(() =>
{
// Code to run
});
}
}
I just find this way cleaner as I don't need to assign variables and then instantiate, it all done in one go.

Categories