So, my solution is to make sure all my view models have a Dispatcher through which to send PropertyChanged events. This has to be bound when they are created, which makes the way I was resolving them from Unity a bit ugly - I must now register a Dispatcher instance in the unity container for it to be all good, or bind it later, when the view model is resolved.
Dispatcher dispatcher;
public Dispatcher Dispatcher
{
get { return dispatcher; }
set { dispatcher = value; }
}
protected virtual void NotifyPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
if (dispatcher != null)
{
dispatcher.BeginInvoke(new CommandExecuteHandler(SendProperty), propName);
}
}
}
void SendProperty(object prop)
{
string propName = prop as string;
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propName));
OnPropertyChanged(propName);
}Another rub is the lack of command binding in Silverlight, when it comes to reusing the view models I had already implemented for silverlight/gtkInstigator. I had stored my commands in a dictionary, and they were resolved through a value converter which would pull them out of the command dictionary by name. Well, for Silverlight, I am putting the command name into the Tag, and use the following code in the click handler:
private void Button_Click(object sender, RoutedEventArgs e)
{
var button = sender as Button;
var dc = DataContext as IViewModel;
if (button != null && dc != null)
{
if (dc.Commands.ContainsKey(button.Tag as string))
{
ICommandWrapper command = dc.Commands[button.Tag as string];
if (command.CanExecute(null))
{
command.Execute(null);
}
}
}
}Problems still to solve: refreshing the enabled/disabled statuses of my buttons, by watching for a PropertyChanged event with "Commands" as a parameter, then iterating through the commands dictionary and available buttons, and setting enabled/disabled to the return of CanExecute.
Passing parameters to commands is another problem which I've yet to have need to solve - all of my commands are simple parameterless actions, so far.
At least ICommand is there, and command binding will likely show up, so using the commanding pattern still makes a lot of sense, even if you have to roll up your sleeves.
No comments:
Post a Comment