Oh boy, this one just drove me insane for over two hours.
First of all, I have a ViewModel that is bound to a user control on a “start page” of my application which is designed to show a Recent Files list. The displaying of this list worked just fine. The ViewModel encapsulates a command member whose execution method is within the ViewModel class itself.
The command is declared and initialized in my view model like this:
public override void InitializeViewModel()
{
FileSelectedCommand = new DelegateCommand<Uri>(FileSelectedCommand_Execute);
base.InitializeViewModel();
}
public DelegateCommand<Uri> FileSelectedCommand { get; protected set; }
The command’s execution method looks like this, but what it’s doing is not what’s important here.
void FileSelectedCommand_Execute(Uri arg)
{
if (arg != null)
{
_RecentDocManager.NotifyDocumentOpened(arg);
OnFileSelected(new FileLocationEventArgs(arg));
}
}
What is important is the argument that it’s set up to receive. Notice that in this case, it’s a URI, which is the exact type to which the CommandParameter argument in my view is bound:
<src:StartPageViewBase.Resources>
<shared:CommandReference x:Key="fileSelectedCommand" Command="{Binding Path=FileSelectedCommand}" />
<ResourceDictionary x:Key="dict1">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Views/SharedResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</src:StartPageViewBase.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding Path=Documents}" DataContext="{Binding}" Grid.IsSharedSizeScope="True" Margin="5,5,5,5">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Style="{DynamicResource {x:Static ribbon:RibbonStyles.ButtonKey}}" HorizontalContentAlignment="Left"
Command="{StaticResource fileSelectedCommand}" CommandParameter="{Binding Path=Location}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=Name}" Margin="0,0,3,0" />
<TextBlock Grid.Column="1" Text="{Binding Path=Location}" ToolTip="{Binding Path=Location}" Margin="0,0,3,0" />
</Grid>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
The problem that drove me crazy was the fact that originally my command was declared with a string in the generic type, and in the case of a delegate-command (or a relay-command as it is otherwise known), the generic type defines the type that the potential argument will be. The CommandParameter argument shown above is bound to a data context member called Location, and this member is a URI, not a string.
The simple mistake of having declared FileSelectedCommand as DelegateCommand<string>, completely disbled the button to which the command is bound.
Uhhhhhhg!
---------------------
On another topic, I haven’t done a very good job regularly posting the “This Week In Code” series. I’m not going to stop doing it, and I promise to try to get back to making it weekly as in the first four, but I’ve been traveling a lot lately and could never guarantee where I’m going to be from one week to the next.
Until next time…