Sto tentando di aggiungere un pulsante a un oggetto ListView personalizzato (MyListView) che attiva un comando (MyCustomCommand) definito in MyListView. Ho aggiunto il pulsante (e un testo del titolo) applicando un ControlTemplate. Il problema è che non ho trovato un modo per attivare MyCustomCommand quando si fa clic sul pulsante. Quello che alla fine voglio ottenere è aprire un Popup o ContextMenu in cui posso selezionare quali colonne dovrebbero essere visibili in ListView.WPF: associa il comando a ControlTemplate
Ecco la mia fonte modello:
<Style TargetType="local:MyListView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyListView">
<Border Name="Border" BorderThickness="1" BorderBrush="Black">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Background="LightSteelBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Margin="3,3,3,3" Text="{TemplateBinding HeaderTitle}" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Stretch" FontSize="16" />
<Button Margin="3,3,3,3" Grid.Column="1"
VerticalAlignment="Center" HorizontalAlignment="Right" Height="20"
Command="{TemplateBinding MyCustomCommand}">A button</Button>
</Grid>
<ScrollViewer Grid.Row="1" Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}">
<ItemsPresenter />
</ScrollViewer>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Ecco la definizione per MyListView:
public class MyListView : ListView
{
public static readonly DependencyProperty MyCustomCommandProperty =
DependencyProperty.Register("MyCustomCommand", typeof(ICommand), typeof(MyListView));
private static RoutedCommand myCustomCommand;
public ICommand MyCustomCommand
{
get
{
if (myCustomCommand == null)
{
myCustomCommand = new RoutedCommand("MyCustomCommand", typeof(MyListView));
var binding = new CommandBinding();
binding.Command = myCustomCommand;
binding.Executed += binding_Executed;
CommandManager.RegisterClassCommandBinding(typeof(MyListView), binding);
}
return myCustomCommand;
}
}
private static void binding_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Command Handled!");
}
public static readonly DependencyProperty HeaderTitleProperty =
DependencyProperty.Register("HeaderTitle", typeof(string), typeof(MyListView));
public string HeaderTitle { get; set; }
}
E qui è il codice XAML che crea una semplice istanza di MyListView:
<local:MyListView VerticalAlignment="Top" HeaderTitle="ListView title">
<ListView.View>
<GridView>
<GridViewColumn Width="70" Header="Column 1" />
<GridViewColumn Width="70" Header="Column 2" />
<GridViewColumn Width="70" Header="Column 3" />
</GridView>
</ListView.View>
<ListViewItem>1</ListViewItem>
<ListViewItem>2</ListViewItem>
<ListViewItem>1</ListViewItem>
<ListViewItem>2</ListViewItem>
</local:MyListView>
Notare HeaderTitle che è associato a DependencyProperty in MyListView. Funziona come previsto. Perché non funziona allo stesso modo con i comandi? Qualche idea su come fare questo lavoro?
Grazie Un sacco. Questo ha risolto il mio caso :) Ora posso aprire un Popup quando il comando viene eseguito. –
Ho incontrato un nuovo problema ... Il pulsante per attivare il comando è disponibile (abilitato) solo nella prima istanza di MyListView in una finestra. Ha qualcosa a che fare con la parola chiave Static in: Command = {x: Static local: MyListView.MyCustomCommand} –
I pulsanti con comandi vengono disabilitati quando CanExecute del comando è falso oppure il comando non ha un gestore Execute collegato. Assicurati di non avere nulla di strano con CanExecute e che CommandBinding sia impostato su ogni istanza di ListView e non in un contesto statico che influenzi solo il primo. –