PropertyChanged remains null even if the property has been changed - wpf

I am struggling with this for a while and I cannot figure it out. I have a button and a textBox. The textBox is linked to a property named: MessageDisplay. I want to be able to access this property and update the textBox in several places. Sadly, the PropertyChanged is null. The weird thing is that if I copy/paste the MessageDisplayModel class into the *MessageViewModel * class, it works ...
here is my code :
XAMLfile :
<Grid>
<Button Command="{Binding DisplayTextCommand}" Name="DisplayTextCommand" Margin="53,72,544.6,286" Width="Auto">Push</Button>
<TextBox Name="MessageDisplay" Text="{Binding MessageDisplay, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</Grid>
MessageDisplayModel file
public class MessageDisplayModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _message;
public string MessageDisplay
{
get { return _message; }
set
{
this._message = value;
this.OnPropertyChanged("MessageDisplay");
}
}
public void UpdateTextBox(string output)
{
MessageDisplay = output;
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}//class
MessageViewModel file:
public class MessageViewModel
{
private ICommand _testCommand;
public MessageDisplayModel MessageDisplaySmt = new MessageDisplayModel();
public ICommand DisplayTextCommand
{
get
{
return new DelegateCommand(DisplayMessage);
}
set
{
if (_testCommand == value) return;
_testCommand = value;
}
}
public void DisplayMessage()
{
MessageDisplaySmt.UpdateTextBox("Successfuly downloaded");
}
}//class
MainWindow file
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MessageDisplay.DataContext = new MessageDisplayModel();
DisplayTextCommand.DataContext = new MessageViewModel();
}
}//class
I update the MessageDisplay property by using the method UpdateTextBox(string). I call this method on the click of the button. When debugging the property gets updated but when time comes to notify the UI that the property has changed, PropertyChangedEventHandler PropertyChanged has its value null ... But if I write something in the textBox, the PropertyChangedEventHandler PropertyChanged gets changed and isn't null anymore. All I want is to be able to change the textBox's property whenever I want and from anywhere I want to.
Thank you

You are using two different instances of MessageDisplayModel. You must use a shared instance.
Also the DisplayTextCommand is implemented "wrong". The set method is redundant as the property's get always returns a new instance of the ICommand.
MessageViewModel.cs
public class MessageViewModel
{
pulic MessageViewModel()
{
}
pulic MessageViewModel(MessageDisplayViewModel messageDisplayViewModel)
{
this.MessageDisplaySmt = messageDisplayViewModel;
}
public void DisplayMessage()
{
this.MessageDisplaySmt.UpdateTextBox("Successfuly downloaded");
}
public MessageDisplayViewModel MessageDisplaySmt { get; set; }
public ICommand DisplayTextCommand { get => new DelegateCommand(DisplayMessage); }
}
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// Alternatively use XAML to set the DataContext (see MainWindow.xaml). Would require a parameterless constructor.
this.DataContext = new MessageViewModel(new MessageDisplayViewModel());
}
}
MainWindow.xaml
<Window>
<!--
Alternative DataContext declaration using XAML instead of C#.
Requires a parameterless constructor for both view model objects.
-->
<Window.DataContext>
<MessageViewModel>
<MessageViewModel.MessageDisplaySmt>
<MessageDisplayViewModel />
</MessageViewModel.MessageDisplaySmt>
</MessageViewModel>
</Window.DataContext>
<StackPanel>
<Button Command="{Binding DisplayTextCommand}"
Content="Push" />
<TextBox Text="{Binding MessageDisplaySmt.MessageDisplay}" />
</StackPanel>
</Window>

Related

WPF MVVM TextBox Update not Occurring

I'm new to WPF MVVM; so, this is a very simple test program exposing a TextBox update issue. Referring to the code below, checking the CheckBox (Name="view1TextBox1" in View1.xml) invokes the property ViewModel1BoolField1 (ViewModel1.cs) where RunTest (Model1.cs) is called. RunTest then returns a string (ViewModel1.cs). This string is then assigned to the ViewModel1StringField1 property. This is where the issue occurs as the TextBox view1TextBox1 (View.xml) is not updated with the test string "Testing 123". I'm not sure if I'm using "OnPropertyChanged" (ViewModelBase.cs) or the the view1TextBox1 "UpdateSourceTrigger=PropertyChanged" (View1.xml) correctly to update the TextBox. Any insight would be great. Thanks!
<UserControl x:Class="WpfMVVMExample1.View.View1"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Orientation="Vertical">
<TextBox Width="100" Height="100" Name="view1TextBox1" TextWrapping="Wrap" AcceptsReturn="True" Text="{Binding ViewModel1StringField1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<CheckBox Name="view1CheckBox1" IsChecked="{Binding ViewModel1BoolField1}"/>
</StackPanel>
</UserControl>
namespace WpfMVVMExample1.ViewModel
{
public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
public void Dispose()
{
this.OnDispose();
}
protected virtual void OnDispose()
{
}
}
}
namespace WpfMVVMExample1.ViewModel
{
class ViewModel1 : ViewModelBase
{
#region Fields
Model1 _model1;
#endregion
#region Constructors
public ViewModel1()
{
_model1 = new Model1 { Model1StringField1 = "Field1" };
}
#endregion
#region Properties
public Model1 Model1
{
set
{
_model1 = value;
}
get
{
return _model1;
}
}
public string ViewModel1StringField1
{
get
{
return Model1.Model1StringField1;
}
set
{
Model1.Model1StringField1 = value;
OnPropertyChanged(ViewModel1StringField1);
}
}
public bool ViewModel1BoolField1
{
get
{
return Model1.Model1BoolField1;
}
set
{
Model1.Model1BoolField1 = value;
if (value)
{
ViewModel1StringField1 = Model1.RunTest();
}
}
}
#endregion
}
}
namespace WpfMVVMExample1.Model
{
class Model1
{
#region Fields
string _model1StringField1;
bool _model1BoolField1;
#endregion
#region Properties
public string Model1StringField1
{
get
{
return _model1StringField1;
}
set
{
_model1StringField1 = value;
}
}
public bool Model1BoolField1
{
get
{
return _model1BoolField1;
}
set
{
_model1BoolField1 = value;
}
}
#endregion
#region Functions
public string RunTest()
{
return "Testing 123";
}
#endregion
}
}
When you call on property changed you are supposed to pass in the property name that changed. Currently you are passing in the value of the property.
OnPropertyChanged(ViewModel1StringField1); }
Should be
OnPropertyChanged("ViewModel1StringField1"); }
If you look at your ViewModelBase class, you'll see this method signature:
protected virtual void OnPropertyChanged(string propertyName)
The parameter of this method is the name of the property that has changed. However, when you invoke it in your ViewModel1StringField1 setter, you do this:
OnPropertyChanged(ViewModel1StringField1);
Instead of the property name, you're passing in its value, which could be anything the user put in. Instead, you want to do this:
OnPropertyChanged("ViewModel1StringField1");
The downside is that the property name is now string and will not be checked by the compiler when you change the name of the property. So just be careful about that (there are alternative ways of doing this).

Why DataContext for inner object is not updated?

I have question about DataContext changes and I build example for understand this aspect.
I have MainUserControl on MainWindow. MainUserControl consists of number of User Controls.
One of such User Controls is SubUserControl1.
<Window x:Class="WpfApplicationUcBindingQuestion.MainWindow">
<Grid>
.....
<uc:MainUserControl />
</Grid>
</Window>
<UserControl x:Class="WpfApplicationUcBindingQuestion.MainUserControl">
<Grid>
.....
<uc:SubUserControl1 x:Name="subUserControl1" />
</Grid>
</UserControl>
And in MainWindow I have object of class Info. Class Info consists of a few inner classes.
One of them is, lets say, SubInfo. Both Info and SubInfo classes inherits from INotifyPropertyChanged.
And this is the code of them:
public class Info : INotifyPropertyChanged
{
private SubInfo m_subInfo = new SubInfo();
public Info()
{
}
public SubInfo SubInfo
{
get
{
return m_subInfo;
}
set
{
m_subInfo = value;
OnPropertyChanged("SubInfo");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public class SubInfo: INotifyPropertyChanged
{
private string m_subString = "subStr";
public SubInfo()
{
}
public string SubString
{
get
{
return m_subString;
}
set
{
m_subString = value;
OnPropertyChanged("SubString");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
I want to set DataContext for MainUserControl to be object of class Info
and for SubUserControl1 DataContext will be Info.SubInfo.
The following code describes this:
<UserControl x:Class="WpfApplicationUcBindingQuestion.SubUserControl1">
<Grid>
.....
<TextBox Text="{Binding Path=SubString}"/>
</Grid>
</UserControl>
public MainUserControl()
{
InitializeComponent();
MainWindow mainWnd = (MainWindow)Application.Current.MainWindow;
Info info = mainWnd.Info;
this.DataContext = info;
this.subUserControl1.DataContext = info.SubInfo;
}
When new subInfo arrived I update inner object subInfo inside info object:
(This is function of MainWindow)
private void OnUpdateData()
{
SubInfo arrivedSubInfo = new SubInfo();
arrivedSubInfo.SubString = "newString";
m_info.SubInfo = arrivedSubInfo;
}
I want to see that DataContext for subUserControl1 is also changed.
But it doesn't happened and TextBox inside SubUserControl1 is not updated
and doesn't show "newString".
(Note: If I write inside OnUpdateData() function the following:
m_info.SubInfo.SubString = arrivedSubInfo.SubString;
(copy field-field and not whole object) it works,
but I dont 'want copy 50 field...)
Where I'm wrong?
Your help will be really appreciated.
Your problem is the following:
In your constructor, when you do that:
this.DataContext = info;
this.subUserControl1.DataContext = info.SubInfo;
You will set the DataContext ONLY once. Which means it will never change unless you write subUserControl1.DataContext = someNewDataContext somewhere.
What you can do to solve this :
The "proper solution":
Use a binding. In your XAML, just write:
<uc:SubUserControl1 x:Name="subUserControl1" DataContext="{Binding
SubInfo, UpdateSourceTrigger=PropertyChanged}" />
This will work, assuming that your SubInfo property fires the OnPropertyChanged event when it is set.
The "ugly solution":
Explicitly set your UserControl's DataContext in code-behind when you need it. Again, I wouldn't advise that and you are better off applying the first solution!

WPF Databinding a Custom Control

So I've spent about two hours pounding my head against the desk trying everything I can think of to bind to a property on a custom control and none of it works. If I have something like this:
<Grid Name="Form1">
<mine:SomeControl MyProp="{Binding ElementName=Form1, Path=DataContext.Enable}"/>
<Button Click="toggleEnabled_Click"/>
</Grid>
public class TestPage : Page
{
private TestForm _form;
public TestPage()
{
InitializeComponent();
_form = new TestForm();
Form1.DataContext = _form;
}
public void toggleEnabled_Click(object sender, RoutedEventArgs e)
{
_form.Enable = !_form.Enable;
}
}
TestForm looks like:
public class TestForm
{
private bool _enable;
public event PropertyChangedEventHandler PropertyChanged;
public bool Enable
{
get { return _enable; }
set { _enable = value; OnPropertyChanged("Enable"); }
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
And my control looks like:
<UserControl>
<TextBox Name="TestBox"/>
</UserControl>
public class SomeControl : UserControl
{
public static readonly DependencyProperty MyPropProperty =
DependencyProperty.Register("MyProp", typeof(bool), typeof(SomeControl));
public bool MyProp
{
get { return (bool)GetValue(MyPropProperty); }
set { SetValue(MyPropProperty, value); }
}
public SomeControl()
{
InitializeComponent();
DependencyPropertyDescriptor.FromProperty(MyPropProperty)
.AddValueChanged(this, Enable);
}
public void Enable(object sender, EventArgs e)
{
TestBox.IsEnabled = (bool)GetValue(MyPropProperty);
}
}
Absolutely nothing happens when I click the toggle button. If I put a breakpoint inside of the Enable callback it is never hit, whats the deal?
If the Enabled method does not do any more than setting the propertou you could drop it and bind the TextBox.IsEnabled directly:
<UserControl Name="control">
<TextBox IsEnabled="{Binding MyProp, ElementName=control}"/>
</UserControl>
If you want to keep such a method you should register a property changed callback via UIPropertyMetadata for the dependency property.
Also this binding is redundant:
{Binding ElementName=Form1, Path=DataContext.Enable}
The DataContext is inherited (if you don't set it in the UserControl (which you should never do!)), so you can just use:
{Binding Enable}
Further if there is trouble with any of the bindings: There are ways to debug them.

how to disable all or some properties PropertyChanged event in WPF?

How to disable all the properties or some of the properties PropertyChanged event for some time when we are using INotifypropertyChanged?
In order for INotifyPropertyChanged to work, you need to raise the PropertyChanged event. Therefore, to make it not work, you just don't raise that event.
Here's a small example class:
public class NPCExample : INotifyPropertyChanged
{
public NPCExample()
{
}
private string mSomeProperty = "Set Property";
public string SomeProperty
{
get { return mSomeProperty; }
set
{
mSomeProperty = value;
if (mUseNotifyPropertyChanged)
NotifyPropertyChanged("SomeProperty");
}
}
private Boolean mUseNotifyPropertyChanged = true;
public Boolean UseNotifyPropertyChanged
{
get { return mUseNotifyPropertyChanged; }
set
{
mUseNotifyPropertyChanged = value;
NotifyPropertyChanged("UseNotifyPropertyChanged");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
In this class, each property calls the common "NotifyPropertyChanged" method for raising the PropertyChanged event. There is an additional variable defined (here, I used a public Property so I could bind it to a checkbox) that tells whether or not to raise the event, as used in the SomeProperty event.
Here's a small, quick-n-dirty program to show this in action:
XAML
<Window x:Class="MyNamespace.SelectiveNotifyPropertyChanged"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SelectiveNotifyPropertyChanged" Height="300" Width="300">
<StackPanel>
<TextBlock Text="{Binding SomeProperty}" />
<CheckBox x:Name="chkINPCEnabled"
Content="Enable INotifyPropertyChanged"
IsChecked="{Binding UseNotifyPropertyChanged}"></CheckBox>
<StackPanel Orientation="Horizontal">
<TextBox x:Name="txtIsProperty"
Text="Set Property" />
<Button x:Name="btnSetProperty"
Content="Set Property" />
</StackPanel>
</StackPanel>
</Window>
Code Behind
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace MyNamespace
{
/// <summary>
/// Interaction logic for SelectiveNotifyPropertyChanged.xaml
/// </summary>
public partial class SelectiveNotifyPropertyChanged : Window
{
public SelectiveNotifyPropertyChanged()
{
InitializeComponent();
NPCExample example = new NPCExample();
this.DataContext = example;
btnSetProperty.Click +=
(s, e) => example.SomeProperty = txtIsProperty.Text;
}
}
public class NPCExample : INotifyPropertyChanged
{
public NPCExample()
{
}
private string mSomeProperty = "Set Property";
public string SomeProperty
{
get { return mSomeProperty; }
set
{
mSomeProperty = value;
if (mUseNotifyPropertyChanged)
NotifyPropertyChanged("SomeProperty");
}
}
private Boolean mUseNotifyPropertyChanged = true;
public Boolean UseNotifyPropertyChanged
{
get { return mUseNotifyPropertyChanged; }
set
{
mUseNotifyPropertyChanged = value;
NotifyPropertyChanged("UseNotifyPropertyChanged");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
If you are referring to a binding, you can set the UpdateSourceTrigger to Explicit, which means any changes won't get saved until you explicitly tell it to update
<TextBox Text="{Binding SomeValue, UpdateSourceTrigger=Explicit}" />
Based on your comment to Rachel it sounds like you might want to set the private property backing member sometimes. Could you expose a public method in your underlying class that would set the private member but not call NotifyPropertyChaged?
Public Class SomeClass
... define property SomeProp and m_SomeProp
Public Sub SetSomeProp(val as string)
m_SomePreop=val
End Sub
End Class

TextBox and Button - Binding and Command

I am using MVVM pattern. I have a
Text box whose Text property is bound to ViewModel's(VM supports INotifyProperyChange) Text property
Button whose command is bound to VM's ICommand property type
You may think of this as a SearchTextBox and SearchButton
The problem I am facing is that when I enter the text in SearchTextBox and click on SearchButton then only the SearchTextBox bound set property implementation is called but the Command for SearchButton click never executes (Note: ICommand CanExecute handler always returns True)
It works fine if I either tab out of SearchTextBox using TAB key or use mouse to move focus away from SearchTextBox and then click the SearchButton. That means do two seperate actions to trigger both the events seperately. Ideally clicking on the SearchButton should result in the SearchTextBox loose focus thus calling Set property and the click on the Search button translates into the command execution.
Code is as below
XAML:
<TextBox Text="{Binding Path=SearchText,Mode=TwoWay}"/>
<Button Content="Search" Width="100" Command="{Binding MySearchCommand}"/>
C#:
public String _SearchText;
public String SearchText
{
get { return _SearchText; }
set
{
_SearchText = value;
OnPropertyChanged("SearchText");
}
}
ICommand implementation is a standard implemenetation with no fancy code and CanExecute handler always returns True
Try to isolate the issue by writing a small test project that reproduces the issue, if you can repro then please post the code. Usually when you repro the issue outside of your main project the problem and the solution become obvious.
I created a sample application to reproduce this problem.
I placed breakpoint and added a Debug.Writeline in SearchText - Set property and MySearchCommandExecute method.
When breakpoints are set, only the SearchText - Set property gets called. I observed that if I remove the breakpoint from SearchText - Set property then both the property and the command are correctly executed. Looks like some problem with VS 2008 but I may be wrong.
The relevant sample code is as below
class SearchViewModel : ViewModelBase
{
public SearchViewModel()
{
}
public String _SearchText;
public String SearchText
{
get { return _SearchText; }
set
{
System.Diagnostics.Debug.WriteLine("Set Membership called");
OnPropertyChanged("SearchText");
}
}
#region Commands
RelayCommand _SearchCommand;
public ICommand SearchCommand
{
get
{
if (_SearchCommand == null)
{
_SearchCommand = new RelayCommand(param => this.MySearchCommandExecute(), param => this.MySearchCommandCanExecute);
}
return _SearchCommand;
}
}
public void MySearchCommandExecute()
{
System.Diagnostics.Debug.WriteLine("MySearchCommandExecute called");
// Do Search
}
public bool MySearchCommandCanExecute
{
get
{
return true;
}
}
#endregion
}
SearchView.xaml
<UserControl x:Class="WpfApplication2.SearchView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<StackPanel>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left" Margin="4">
<Label Foreground="Black" FontFamily="Calibri" Width="155" Margin="4,0,4,0" Content="SearchText"/>
<TextBox Foreground="Black" FontFamily="Calibri" Width="155" Margin="4,0,4,0" Text="{Binding Path=SearchText}"/>
</StackPanel>
<Button HorizontalAlignment="Left" Content="Search" Width="100" Command="{Binding SearchCommand}" Margin="8"/>
</StackPanel>
</UserControl>
RelayCommand.cs
// Reference: MSDN sample
class RelayCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("relaycommand execute");
_execute = execute;
_canExecute = canExecute;
}
[DebuggerStepThrough]
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);
}
}
Byte,
Sorry for my late response, but I hope it will become handy anyway. I'm very busy lately so I couldn't debug your code (I'll try to do that when I have more time), but please try my sample code pasted below (It works perfectly for me). As you can see it's extremely simple. I used your xaml, but for Window:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new TempViewModel();
}
}
public class TempViewModel : INotifyPropertyChanged
{
private String _searchText;
private ICommand _searchCommand;
#region Commands
protected class Search : ICommand
{
private TempViewModel _viewModel;
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged
{
add { }
remove { }
}
public void Execute(object parameter)
{
//MessageBox in VM is just for demonstration
MessageBox.Show("command executed with search string: " + this._viewModel._searchText);
}
public Search(TempViewModel viewModel)
{
this._viewModel = viewModel;
}
}
#endregion //Commands
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(String propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion //INotifyPropertyChanged
#region Public properties
public String SearchText
{
get
{
return this._searchText;
}
set
{
this._searchText = value;
OnPropertyChanged("SearchText");
}
}
public ICommand SearchCommand
{
get
{
return this._searchCommand;
}
set
{
this._searchCommand = value;
OnPropertyChanged("SearchCommand");
}
}
#endregion //Public properties
public TempViewModel()
{
this.SearchCommand = new Search(this);
this.SearchText = "Sample string";
}
}
Please feel free to ask if you have any further questions.
EDIT: Ah, sorry, but I changed Command="{Binding SearchCommand}" to Command="{Binding Path=SearchCommand}"

Resources