I think I've found a bug in the Prism for Windows Runtime library, but I'd like to know if there's a work around or a way to fix the issue without forking the project myself...
I'm trying to display a list of items in an ItemsControl. Each item has a button, which when clicked should execute a command on the parent control's data context and pass the item's ID as the command parameter. Basically, I'm trying to render a list of items and have a delete button for each item. To accomplish this, I'm following this code sample, which I've so far found as the only clean way to accomplish this feat.
Unfortunately, the DelegateCommand<T>
class implemented by Prism for Windows Runtime seems to not play well with the XAML binding parser. When everything is hooked up, I receive this exception when the page tries to render:
Failed to assign to property 'Windows.UI.Xaml.Controls.Primitives.ButtonBase.Command'. [Line: 61 Position: 49]
I created a new project and simplified my production example to test my theory that this is an issue with DelegateCommand<T>
(which is needed to allow a parameter to be passed to the delegate method). I implemented two commands, one using DelegateCommand<T>
and one just using DelegateCommand
. The one using DelegateCommand
doesn't cause an exception, but I lose the ability to accept a command parameter which means I can't identify which item was to be deleted.
The XAML:
<ItemsControl Name="TestControl" Grid.Row="1" ItemsSource="{Binding MyItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}" Command="{Binding DataContext.BrokenCommand, ElementName=TestControl}" CommandParameter="1" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The View Model:
public DelegateCommand<int> BrokenCommand { get; set; }
public DelegateCommand WorkingCommand { get; set; }
public List<string> MyItems { get { return new List<string> {"A", "B", "C"}; } }
public MainPageViewModel(INavigationService navigationService)
{
BrokenCommand = new DelegateCommand<int>(BrokenMethod);
WorkingCommand = new DelegateCommand(WorkingMethod);
}
private void BrokenMethod(int i)
{
throw new NotImplementedException();
}
private void WorkingMethod()
{
throw new NotImplementedException();
}
try this
BrokenCommand = new DelegateCommand<string>
(id => BrokenMethod(Convert.ToInt32((id));
I just tested it, and it works if you change your T to string as it comes as a string.
Hopefully somebody can explain why :)