I'm using two views which refers same view model. Both of my views contain a text box that binds to a value in the view model. My problem is that, if I change the value of textbox in one GUI, its not reflecting in another. What should I do to achieve this?
This is my view model
public class ProductViewModel:INotifyPropertyChanged
{
private int machineheight;
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
public int MachineHeight
{
get
{
return this.machineheight;
}
set
{
this.machineheight = value;
RaisePropertyChanged("MachineHeight");
}
}
public ProductViewModel()
{
}
private ICommand mUpdater;
public ICommand UpdateCommand
{
get
{
if (mUpdater == null)
mUpdater = new Updater();
return mUpdater;
}
set
{
mUpdater = value;
}
}
private class Updater : ICommand
{
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
SecondWindow w = new SecondWindow();
w.Show();
}
#endregion
}
}
}
The second window is another GUI. Once I click update button, second window opened. But the value that I have changed in first UI is not updated in the new window.
My Xaml is similar for both UI..
<Window x:Class="WPFDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFDemo"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ProductViewModel/>
</Window.DataContext>
<Grid Height="307" Width="480" Initialized="Grid_Initialized">
<Button Content="Update" Height="32" HorizontalAlignment="Left" Margin="165,158,0,0" Name="button1" VerticalAlignment="Top" Width="114" Command="{Binding Path=UpdateCommand}"/>
<TextBox Height="42" HorizontalAlignment="Left" Margin="125,82,0,0" Name="textBox1" VerticalAlignment="Top" Width="169" Text= "{Binding Path= MachineHeight, Mode=TwoWay}" />
</Grid>
</Window>
I actually don't know what is the problem.. thanks
<Window.DataContext>
<local:ProductViewModel/>
</Window.DataContext>
hi, if you put this in your 2 views, then each one has its own viewmodel. so you will never see any changes. you have to set the datacontext from your first view to your second view. Btw for your ICommand implementation look at some mvvm frameworks for easier implementations, eg RelayCommand, DelegateCommand.
For your actual implementation you can add the following to your xaml and ViewModel(CommandParameter) then it works.
<Button Content="Update" Height="32" HorizontalAlignment="Left" Margin="165,158,0,0" Name="button1" VerticalAlignment="Top" Width="114" Command="{Binding Path=UpdateCommand}"
CommandParameter="{Binding .}"/>
public void Execute(object parameter)
{
SecondWindow w = new SecondWindow();
w.DataContext = parameter;
w.Show();
}
There are a hundred things that can go wrong in this scenario, and one of my long-standing gripes with XAML-based databinding is that the MS tools give you precious little help figuring out which of those hundred things it is. This is especially the case if you're new to databinding, but even folks who've been doing it for years can spend obnoxious hours tracking down databinding issues.
Some things to check:
(1) Confirm that your databindings are two-way.
(2) Look in your debug output window to see if there are any error messages there.
(3) Set an IValueConverter in your databinding, and set a breakpoint in the converter to see what data is being passed where and when.
(4) Confirm that the data in the ViewModel is actually being updated.
(5) Confirm that the ViewModel implements INotifyPropertyChanged, and that the PropertyChanged event is firing.
(6) Post your actual code here so folks can look at it.
And so forth.
Hope this helps.
It must work if the ViewModel implements INotifyPropertyChanged.
Related
I'm learning WPF.
In one of the exercises, I have a TextBox and buttons Cut and Paste. The following is enough to implement Cut and Paste functionality:
XAML:
<DockPanel>
<WrapPanel DockPanel.Dock="Top" Margin="3">
<Button Command="ApplicationCommands.Cut"
CommandTarget="{Binding ElementName=txtEditor}"
Width="60">
_Cut
</Button>
<Button Command="ApplicationCommands.Paste"
CommandTarget="{Binding ElementName=txtEditor}"
Width="60" Margin="3,0">
_Paste<
/Button>
</WrapPanel>
<TextBox AcceptsReturn="True" Name="txtEditor" />
</DockPanel>
When pressed, the button Cut executes the ApplicationCommands.Cut on the TextBox with name txtEditor. When needed, the button will ask the TextBox with name textEditor if it can execute a Cut command, and when pressed it will order the textEditor to execute the Cut command.
Fairly straightforward. It works fine.
Just for Fun, I'd like to implement another button: Clear. When pressed it should clear the TextBox. The Textbox class has a method Clear.
<Button Command="ApplicationCommands.Clear"
CommandTarget="{Binding ElementName=txtEditor}"
Width="60">
Clear
</Button>
Alas, this won't work. ApplicationCommands doesn't have a Clear. Should I implement a custom command, as suggested in this example?
I tried the following:
I implemented CanExecute and Executed methods in my window:
public partial class CustomCommandSample : Window
{
public CustomCommandSample()
{
InitializeComponent();
}
private void ClearCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void ClearCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
txtEditor.Clear();
}
}
A static CustomCommands class:
public static class CustomCommands
{
public static RoutedUICommand Clear => new RoutedUICommand (
"Clear",
"Clear",
typeof(CustomCommands));
}
Finally the XAML:
(Note: the classes in this project are in namespace WpfCommandDemo. Xaml refers to it as Local)
<Window x:Class="WpfTutorialSamples.Commands.UsingCommandsSample"
xmlns="...
xmlns:local="clr-namespace:WpfCommandDemo"
Title="UsingCommandsSample" Height="100" Width="200">
<Window.CommandBindings>
<CommandBinding Command="CustomCommands.Clear"
CanExecute="ClearCommand_CanExecute"
Executed="ClearCommand_Executed" />
</Window.CommandBindings>
<DockPanel>
<WrapPanel DockPanel.Dock="Top" Margin="3">
<Button Command="CustomCommands.Clear"
CommandTarget="{Binding ElementName=txtEditor}"
Width="60">
Clear
</Button>
... (other buttons: cut / paste, as above
</WrapPanel>
<TextBox AcceptsReturn="True" Name="txtEditor" />
</DockPanel>
Although this compiles, The constructor of CustomCommandSample throws an XamlParseException:
Type reference cannot find type named
'{http://schemas.microsoft.com/winfx/2006/xaml/presentation}CustomCommands'.
Should I solve the problem using Custom Commands? What should I change? Or am I completely wrong, and should I solve this differently
To use CustomCommands in XAML, you'll need to add a reference to it. In the element, add a line:
xmlns:custom="clr-namespace:MyApplication.NamespaceWithCustomInIt"
Replacing the namespace value as appropriate. Then you should be able to reference CustomCommands anywhere in XAML as custom:CustomCommands (may have to bind, I'll check later).
Should I solve the problem using Custom Commands?
Yes. This is how to solve this using the Model-View-ViewModel (MVVM) design pattern which is the recommended design pattern to use when developing XAML based UI applications.
From this blog post:
WPF provides two implementations of the ICommand interface; the System.Windows.Input.RoutedCommand and System.Windows.Input.RoutedUICommand where the latter is a subclass of the former that simply adds a Text property that describes the command. However, neither of these implementations are especially suited to be used in a view model as they search the visual tree from the focused element and up for an element that has a matching System.Windows.Input.CommandBinding object in its CommandBindings collection and then executes the Execute delegate for this particular CommandBinding. Since the command logic should reside in the view model, you don’t want to setup a CommandBinding in the view in order to connect the command to a visual element. Instead, you can create your own command by creating a class that implements the ICommand. The below implementation is a common one that invokes delegates for the Execute and CanExecute methods:
public class DelegateCommand: System.Windows.Input.ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _execute;
public DelegateCommand(Action<object> execute)
: this(execute, null) { }
public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => _canExecute == null ? true : _canExecute(parameter);
public void Execute(object parameter) => _execute(parameter);
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
Once you have an implementation of the ICommand interface, it's easy to use in your view models:
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
ClearCommand = new DelegateCommand(Clear);
}
private string _text;
public string Text
{
get { return _text; }
set { _text = value; NotifyPropertyChanged(); }
}
public ICommand ClearCommand { get; }
private void Clear(object parameter)
{
Text = string.Empty;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
In the view, you simply bind to the properties of the view model:
<TextBox AcceptsReturn="True" Name="txtEditor" Text="{Binding Text}" />
<Button Content="Clear" Command="{Binding ClearCommand}" />
Just remember to set the DataContext of the view to an instance of your view model for the bindings to work:
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
I have an app that uses MVVM pattern and implements INotifyPropertyChanged but it's not working. Basically when I choose a Wine from a list and click 'open', another usercontrol should load with all the details filled in.
I followed along with a pluralsight course and have tried to adapt it and create something of my own. I have gone through the source code of the pluralsight course and stack-overflow questions for many hours and just can't see what I'm missing. Going crazy here.. :(
After alot of searching, I know my databinding is working, because I can force an update to the target like so:
txtWijnNaam.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
I also tried adding the INotifyPropertyChanged to my Wine model class as well as the viewmodel but this didn't work. And it's also not used like this in the working source code of the pluralsight course so shouldn't be necessary.
The viewmodel I'm using:
class WineDetailViewModel : ViewModelBase
{
private readonly string _baseUri = "https://localhost/api/wines";
private IEventAggregator _eventAggregator;
public WineDetailViewModel()
{
_eventAggregator = EventAggregatorSingleton.Instance;
_eventAggregator.GetEvent<OpenWineDetailViewEvent>().Subscribe(OnOpenWineDetailView);
}
private void OnOpenWineDetailView(int wineId)
{
_wine = ApiHelper.GetApiResult<Wine>($"{ _baseUri}/{wineId}");
}
private Wine _wine;
public Wine WineFull
{
get { return _wine; }
set
{
_wine = value;
OnPropertyChanged();
}
}
}
And the base class it inherits from, implementing the INotifyPropertyChanged interface:
class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Part of my Xaml file, I tried setting updateSourceTrigger like I saw on some answers here but this didn't help either:
<UserControl x:Class="WineGUI.View.WineDetailView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WineGUI.View"
xmlns:ViewModels="clr-namespace:WineGUI.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<ViewModels:WineDetailViewModel/>
</UserControl.DataContext>
<StackPanel>
<Grid Margin="5">
<TextBlock Text="Naam :" VerticalAlignment="Center"/>
<TextBox Grid.Column="1" Name="txtWijnNaam" Margin="5" Text="{Binding WineFull.Name, Mode=TwoWay}"/>
<TextBlock Grid.Row="1" Text="Jaar :" VerticalAlignment="Center"/>
<TextBox Grid.Row="1" Grid.Column="1" Name="txtWijnYear" Margin="5" Text="{Binding WineFull.Year, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Grid.Row="2" Text="Prijs :" VerticalAlignment="Center"/>
I do notice the OnPropertyChanged() method of my WineFull property is never called but I don't get why. The pluralsight course has an identical set-up (except for some naming of course) and it works just fine..
Any help would be much appreciated. If I need to add any more info or code, please let me know.
You are setting the value of the backing field not the property so the OnPropertyChanged method is never called.
You can call OnPropertyChanged for the WineFull property in the OnOpenWineDetailView method:
private void OnOpenWineDetailView(int wineId)
{
_wine = ApiHelper.GetApiResult<Wine>($"{ _baseUri}/{wineId}");
OnPropertyChanged(nameof(WineFull));
}
Or you can use the property:
private void OnOpenWineDetailView(int wineId)
{
WineFull= ApiHelper.GetApiResult<Wine>($"{ _baseUri}/{wineId}");
}
I'm trying to implement the MVVM, so i dont know the following is correct.
It seems that ViewModel is some kind of model of the view, so associations in view shall be shown in ViewModel, in that case there shall be some associations between ViewModels. so by creating some templates for ViewModel Types, it seems the application can work, here is some example code:
ViewModels:
public class SomeVm : INotifyPropertyChanged
{
public SomeVm()
{
SomeOtherVm = new SomeOtherVm();
}
public INotifyPropertyChanged SomeOtherVm { set; get; }
private int _a;
public int A
{
set {
_a= value;
B = value;
}
get { return _a; }
}
private int _b;
public int B
{
set
{
_b = value;
OnPropertyChanged("B");
}
get { return _b; }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class SomeOtherVm : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _c;
public int C
{
set
{
_c = value;
D = value;
}
get { return _c; }
}
private int _d;
public int D
{
set
{
_d = value;
OnPropertyChanged("D");
}
get { return _d; }
}
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
And the View:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="WpfApplication1.MainWindow"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<wpfApplication1:SomeVm x:Key="SomeVm"/>
<DataTemplate DataType="{x:Type wpfApplication1:SomeVm}">
<StackPanel d:DesignWidth="339" d:DesignHeight="54">
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding A}" VerticalAlignment="Stretch"/>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding B}" VerticalAlignment="Stretch"/>
<ContentPresenter Content="{Binding SomeOtherVm}"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type wpfApplication1:SomeOtherVm}">
<StackPanel d:DesignWidth="339" d:DesignHeight="54">
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding C}" VerticalAlignment="Stretch"/>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding D}" VerticalAlignment="Stretch"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ContentPresenter Content="{DynamicResource SomeVm}" />
</Grid>
</Window>
in this way all the views can be created in some Resource Dictionaries, so the question is: is it right to use MVVM like this? And if it is, what is the drawbacks?
Usually ViewModel is supposed to be the DataContext for the whole view i.e it should be the entity incharge of providing Data to view to render itself and to listen to UI command, events and property change to interact with the Business Layer (model).
The way you implemented it is you have your VM as a resource and set it as content not DataContext for one contentpresented and for the scenerio you have mentioned it might work well. But you should set VM as the DataContext for the whole view so that all the elements in the view can bind to the properties in the VM to render their state.
In your scenerio, if you have to add one more UI element in you view apart from the ContentPresenter then again you will have to access your resource VM.
So if you set you VM instance as DataContext (like this.DataContext = new ViewModel()) and bind your contentpresenter Content to DataContext of view like Content={Binding} that will be more correct and will help you if you ever want to extend your view. Here is a nice msdn article regarding mvvm implementation http://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx
Thanks
Speaking in terms of ViewModel nesting, this code looks correct at a glance. Bindings you set up in XAML are also correct.
Concerning drawbacks, I would refrain from creating wpfApplication1:SomeVm in window resources. Usually DataContext of the Window is set to an instance of a WindowViewModel, which would in turn hold a reference to SomeVm. Imagine a class like this:
public class WindowViewModel
{
public SomeVM SomeVM{get; set;}
public string Title {get; set;} //other data to bind by window
//...
}
Then, while the window is initialized, DataContext must be set to a ViewModel instance, e.g:
MainWindow.DataContext = new WindowViewModel();
In XAML you'd use bindings again:
<Grid>
<ContentPresenter Content="{Binding SomeVm}" />
</Grid>
I'd also recommend putting your implicit DataTemplates in generic.xaml dictionary, rather then within a window. This way you can reuse these templates in your whole app.
Moreover, it is far better to use a ViewModelBase class implementing common event handling, so that you don't need to reimplement INotifyPropertyChanged. Also try to avoid "magic strings" in property change notification. Be better off using lambda based approach or the new Caller Info Attributes. I'm aware of that your example code is probably simplified, but I'm commenting on it as it is.
Time for my first question :)
I have the following:
public class BuilderViewModel : INotifyPropertyChanged
{
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private double _contentScale = 1.0;
public double ContentScale
{
get { return _contentScale; }
set
{
_contentScale = value;
NotifyPropertyChanged("ContentScale");
}
}
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#region Commands
bool CanZoomIn() { return true; }
void ZoomInExecute()
{
ContentScale += 1.0;
}
public ICommand ZoomIn { get { return new RelayCommand(ZoomInExecute, CanZoomIn); } }
#endregion
}
And the corresponding view:
<UserControl x:Class="PS_IDE.FormBuilder.View.Builder"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PS_IDE.FormBuilder.ViewModel">
<UserControl.DataContext>
<local:BuilderViewModel />
</UserControl.DataContext>
<TextBox Text="{Binding ContentScale}" Width="100" />
</UserControl>
I'm trying to have the ZoomIn command in BuilderViewModel update the text box value in it's view. The command is being fired from another user control, UIBuilder, which includes Builder. If I debug and fire the command from UIBuilder, I can see it updating ContentScale properly.
However, my text box value does not get updated (it only says "1", which is the initial value of ContentScale).
I know I'm missing something and hope someone can point me in the right direction.
EDIT: Added the control that is firing the command
<UserControl x:Class="PS_IDE.FormBuilder.UIBuilder"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PS_IDE.FormBuilder"
xmlns:ViewModel="clr-namespace:PS_IDE.FormBuilder.ViewModel"
xmlns:View="clr-namespace:PS_IDE.FormBuilder.View" mc:Ignorable="d">
<UserControl.DataContext>
<ViewModel:BuilderViewModel />
</UserControl.DataContext>
<DockPanel LastChildFill="True">
....
<ToolBarTray DockPanel.Dock="Bottom" HorizontalAlignment="Right">
<ToolBar>
<Button Height="24" Width="24" ToolTip="Zoom In" Command="{Binding ZoomIn}">
<Image Source="Images/ZoomIn.png" Height="16"/>
</Button>
....
</ToolBar>
</ToolBarTray>
<View:Builder x:Name="builder" />
</DockPanel>
</UserControl>
With the setting in both view:
<UserControl.DataContext>
<local:BuilderViewModel />
</UserControl.DataContext>
you are basically creating two viewmodels, one for each view. So when your Command updates the property it does it on one of the viewmodel but your textbox is bound to a different viewmodel.
To resolve it remove the DataContext setting from the Builder.xaml
Additionally you need to pass your DataContext to your Builder control (with this both view will share the same viewmodel).
So modify your UIBuilder.xaml:
<View:Builder x:Name="builder" DataContext="{Binding}" />
Use Mode TwoWay in your binding
Text ="{Binding ElementName=BuilderViewModel,
Path=ContentScale,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
Nota : use observable collection in order to send notify
I created a button whose commandparameter is set and command using a class that implements ICommand interface. But my button is disabled. Why is that? I got this code from here: ICommand is like a chocolate cake
<Window x:Class="ICommand_Implementation_CSharp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ICommand_Implementation_CSharp"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid>
<Grid.Resources>
<local:HelloWorldCommand x:Key="hwc" />
</Grid.Resources>
<Button Command="{StaticResource hwc}" CommandParameter="Hello"
Height="23" HorizontalAlignment="Left" Margin="212,138,0,0"
Name="Button1" VerticalAlignment="Top" Width="75">Button</Button>
</Grid>
</Grid>
and my class is
class HelloWorldCommand:ICommand
{
public bool CanExecute(object parameter)
{
return parameter != null;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
MessageBox.Show(parameter.ToString());
}
}
Well, this is very-very simple implementation of ICommand.
As #JleruOHeP says, partially problem can be solved by swapping setters of Command and CommandParameter. But this is ugly way, because you have to remember the sequence every time.
More correct way is to tell CommandManager to re-query states of command:
public class HelloWorldCommand : ICommand
{
public bool CanExecute(object parameter)
{
return parameter != null;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
MessageBox.Show(parameter.ToString());
}
}
Now the sequence of setters is indifferent.
To understand how CommandManager works, you can read this nice article from Josh Smith.
The simplest answer - switch places of Command and Command parameter:
<Button CommandParameter="Hello" Command="{StaticResource hwc}" .../>
But better one is given by #Dennis
In my case it was the CommandParameter type that was causing the issue. My button was simply bound like this:
<Button Content="New" Command="{Binding NewCommand}" CommandParameter="False" />
The underlying NewCommand is a RelayCommand<bool>. Somehow XAML was not able to translate False to bool. (Note that it does work for many built-in types and properties; maybe some TypeConverter or something at action there).
Solution was to simply spoon-feed XAML about the real underlying type of CommandParameter, like this:
<Button Content="New" Command="{Binding NewCommand}">
<Button.CommandParameter>
<sys:Boolean>
False
</sys:Boolean>
</Button.CommandParameter>
</Button>
You have to import sys namespace at the top of your XAML file, like this:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Hope this helps someone down the road.