Well after fiddling with MVVM light to get my button to enable and disable when I want it to... I sort of mashed things together until it worked.
However, I just know I'm doing something wrong here. I have RaiseCanExecuteChanged and CanExecute in the same area being called. Surely this is not how it's done?
Here's my xaml
<Button Margin="10, 25, 10, 25" VerticalAlignment="Center" HorizontalAlignment="Center" Width="50" Height="50" Grid.Column="1" Grid.Row="3" Content="Host">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<mvvmLight:EventToCommand Command="{Binding HostChat}" MustToggleIsEnabled="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
And here's my code
public override void InitializeViewAndViewModel()
{
view = UnityContainer.Resolve<LoginPromptView>();
viewModel = UnityContainer.Resolve<LoginPromptViewModel>();
view.DataContext = viewModel;
InjectViewIntoRegion(RegionNames.PopUpRegion, view, true);
viewModel.HostChat = new DelegateCommand(ExecuteHostChat, CanHostChat);
viewModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(ViewModelPropertyChanged);
}
void ViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "Name" || e.PropertyName == "Port" || e.PropertyName == "Address")
{
(viewModel.HostChat as DelegateCommand).RaiseCanExecuteChanged();
(viewModel.HostChat as DelegateCommand).CanExecute();
}
}
public void ExecuteHostChat()
{
}
public bool CanHostChat()
{
if (String.IsNullOrEmpty(viewModel.Address) ||
String.IsNullOrEmpty(viewModel.Port) ||
String.IsNullOrEmpty(viewModel.Name))
{
return false;
}
else
return true;
}
See how these two are together? Surely that can't be right. I mean... it WORKS for me... but something seems wrong about it. Shouldn't RaiseCanExecuteChanged call CanExecute? It doesn't... and so if I don't have that CanExecute in there, my control never toggles its IsEnabled like I need it to.
(viewModel.HostChat as DelegateCommand).RaiseCanExecuteChanged();
(viewModel.HostChat as DelegateCommand).CanExecute();
EDIT:
If I end up using the Command property of button to bind my command to... everything works fine. I can remove the CanExecute and just leave the RaiseCanExecuteChanged and everything works brilliantly.
Like this... this works just fine.
<Button Command="{Binding HostChat}" Margin="10, 25, 10, 25" VerticalAlignment="Center" HorizontalAlignment="Center" Width="50" Height="50" Grid.Column="1" Grid.Row="3" Content="Host">
</Button>
void ViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "Name" || e.PropertyName == "Port" || e.PropertyName == "Address")
{
(viewModel.HostChat as DelegateCommand).RaiseCanExecuteChanged();
//(viewModel.HostChat as DelegateCommand).CanExecute();
//CommandManager.InvalidateRequerySuggested();
}
}
CanExecute
method only returns whether the command can be executed or not. It doesn't do anything else. You only need RaiseCanExecuteChanged
. RaiseCanExecuteChanged
will call CanHostChat
in your case.