I'm trying to execute methods based on listview items data. In addition to that, the button, which triggers the command, should only be enabled, if "CanExecute" method of the listview item returns true.
Both methods, "MyCommand" and "CanExecute", are included in my ViewModel. Unfortunately I'm not sure how to pass the items information correctly to both methods in order to be conform with the PRISM 6 framework.
So my first approach was to do it like the following :
Model
public class MyModel
{
public string Name { get; set; }
public string Version { get; set; }
public int Identifier { get; set; }
}
ViewModel
public class MyViewModel : BindableBase
{
private ObservableCollection<MyModel> _models = new ObservableCollection<MyModel>();
public ObservableCollection<MyModel> Models
{
get { return _models; }
set { SetProperty(ref _models, value); }
}
public DelegateCommand VerifyCommand { get; set; }
public MyViewModel()
{
//Add test data
for (int i = 0; i < 5; i++)
{
MyModel model = new MyModel();
model.Name = "Random Text";
model.Version = "Random Text";
model.Identifier = i;
Models.Add(model);
}
//Doesn't work, because I don't reference to "Models"
//How to do that?
VerifyCommand = new DelegateCommand(DoCommand, CanExecute).ObservesProperty<string>(() => Name).ObservesProperty<string>(() => Version);
}
private bool CanExecute()
{
//Obviously this doesn't work, because "Version" and "Name"
//don't belong to the selected "Models" item of the listview
//What is the "bridge", to know which item of Models was clicked (button)
return !String.IsNullOrWhiteSpace(Version) && !String.IsNullOrWhiteSpace(Name);
}
private void DoCommand()
{
//Do something special
}
}
View
<ListView ItemsSource="{Binding Models}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="Auto" Margin="0,0,0,10">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Tag="VERSION" Text="{Binding Version, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Grid.Row="1" Tag="NAME" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
<Button Command="{Binding ElementName=root, Path=DataContext.VerifyCommand}" Content="Verify" Grid.Row="2">
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The link between View and ViewModel is done by using:
prism:ViewModelLocator.AutoWireViewModel="True"
in my View (this works).
So in summary: How does it work, PRISM conform, to 1. Enable the items button only if CanExecute is true and 2. to execute "DoCommand" method and passing items information to that (root element of the button -> In this case the ListViewItem (MyModel).
Any help would be greatly appreciated.
Models
property probably needs no setter, unless you plan to set it from the outside (by databinding)... – Highly