2016-11-24 3 views
0

Я вытаскиваю элементы из БД в список, состоящий из нескольких столбцов. Я хотел бы добавить кнопку удаления для каждого элемента я тянуть из БД, но я не могу передать идентификатор элемента, он всегда говорит 0.WPF Prism listbox button

<ListBox ItemsSource="{Binding LbPlugins}" HorizontalContentAlignment="Stretch" Grid.Row="1"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Grid HorizontalAlignment="Stretch"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="5*"/> 
        <ColumnDefinition Width="5*"/> 
        <ColumnDefinition Width="*"/> 
        <ColumnDefinition Width="*"/> 
       </Grid.ColumnDefinitions> 

       <CheckBox Grid.Column="0" Content="{Binding Name}" IsChecked="{Binding IsActive}"/> 
       <Label Grid.Column="1" Content="{Binding ClassName}"/> 
       <Button Grid.Column="2" Content="E" Command="{Binding btnEditPluginCommand}"/> 
       <Button Grid.Column="3" Content="D" Command="{Binding Path=DataContext.btnDeletePluginCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding PluginId}"/> 

      </Grid> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

В ViewModel:

private int pluginId; 
    public int PluginId 
    { 
     get { return pluginId; } 
     set { SetProperty(ref pluginId, value); } 
    } 
    public DelegateCommand btnDeletePluginCommand { get; set; } 

...

в конструкторе

btnDeletePluginCommand = new DelegateCommand(DeletePlugin); 

...

private void DeletePlugin() 
{ 
    var result = MessageBox.Show("Are you sure you want to delete this plugin?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); 
    if (result == DialogResult.Yes) 
    { 
     MessageBox.Show("YAY, ID=" + pluginId); 
    } 
} 

ответ

1

Как вы используете Prism вас следует использовать DelegateCommand, то есть реализацию Признака ICommand.

Для выполнения этой работы вам необходимо использовать объект или тип NULL как аргумент для общего CommandDelegate. Если вы этого не сделаете, вы получите InvalidCastException во время выполнения.

Объявите вашу команду:

public ICommand btnDeletePluginCommand { get; set; } 

Инициализировать его конструктор ViewModel в:

btnDeletePluginCommand = new DelegateCommand<int?>(DeletePlugin); 

И реорганизовать метод:

private void DeletePlugin(int? pluginId) 
{ 
    if (pluginId == null) return; 

    var result = MessageBox.Show("Are you sure you want to delete this plugin?", "", MessageBoxButtons.YesNo, 
     MessageBoxIcon.Warning); 
    if (result == DialogResult.Yes) 
     MessageBox.Show("YAY, ID=" + pluginId); 
} 

Как вы связали команду с ListBox, параметр pluginId никогда не будет пустым, но вы всегда должны проверять. Может быть, вы используете эту модель с другими компонентами пользовательского интерфейса?

Кстати, вы не должны использовать MessageBox в viewmodel. Я думаю, это доказательство концепции или чего-то еще :). В случае MVVM вы должны ввести DialogService или использовать InteractionRequests для отображения уведомлений с вашей модели просмотра.

Надеюсь, это поможет!

0

Поскольку вы уже умирала параметр из XAML, вы можете использовать:

btnDeletePluginCommand = new Microsoft.Practices.Prism.Commands.DelegateCommand<int>(DeletePlugin); 

И тогда ваш DeletePlugin должен иметь один параметр, как это:

private void DeletePlugin(int pluginId) 
{ 
    ... 
}