[英]Passing ListView Items to Commands using Prism Library
我正在嘗試基於listview項數據執行方法。 除此之外,如果listview項的“CanExecute”方法返回true,則只應啟用觸發命令的按鈕。
“MyCommand”和“CanExecute”這兩種方法都包含在我的ViewModel中。 不幸的是,我不確定如何正確地將項目信息傳遞給兩種方法,以便符合PRISM 6框架。
所以我的第一個方法是像下面這樣做:
模型
public class MyModel
{
public string Name { get; set; }
public string Version { get; set; }
public int Identifier { get; set; }
}
視圖模型
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
}
}
視圖
<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>
View和ViewModel之間的鏈接使用:
prism:ViewModelLocator.AutoWireViewModel="True"
在我的視圖中(這是有效的)。
所以總結:它是如何工作的,PRISM符合,1。只有當CanExecute為真時才啟用項目按鈕; 2.執行“DoCommand”方法並將項目信息傳遞給它(按鈕的根元素 - >在這種情況下ListViewItem(MyModel)。
任何幫助將不勝感激。
簡短回答:將命令放在項目的viewmodel中。
答案很長:
以下是我在上述評論中的含義示例。 我已經省略了集合的可觀察性,如果你真的需要一個可觀察的模型集合和一個可觀察的視圖模型集合,那么就要為很多無聊的雙向同步代碼做好准備......
模型:
internal class ItemModel
{
public string Name { get; set; }
public string Version { get; set; }
public int Identifier { get; set; }
}
ViewModels(一個用於項目集合,即MyViewModel
,一個用於項目):
internal class MyCollectionViewModel : BindableBase
{
private readonly List<ItemModel> _models = new List<ItemModel>();
public MyCollectionViewModel()
{
//Add test data
for (var i = 0; i < 5; i++)
_models.Add( new ItemModel
{
// to prove that CanExecute is actually evaluated...
Name = i == 3 ? "Random Text" : string.Empty,
Version = "Random Text",
Identifier = i
} );
}
public IReadOnlyCollection<ItemViewModel> TheCollection => _models.Select( x => new ItemViewModel( x ) ).ToList();
}
internal class ItemViewModel : BindableBase
{
public ItemViewModel( ItemModel item )
{
_item = item;
VerifyCommand = new DelegateCommand( () =>
{
/* Do something */
}, () => !string.IsNullOrWhiteSpace( Version ) && !string.IsNullOrWhiteSpace( Name ) );
}
public string Name => _item.Name;
public string Version => _item.Version;
public int Identifier => _item.Identifier;
public DelegateCommand VerifyCommand
{
get;
}
private readonly ItemModel _item;
}
視圖:
<ListView ItemsSource="{Binding TheCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="Auto" Margin="0,0,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding Version, Mode=OneWay}" />
<TextBox Grid.Column="1" Text="{Binding Name, Mode=OneWay}" />
<Button Grid.Column="2" Command="{Binding VerifyCommand}" Content="Verify"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.