Ich muss eine benutzerdefinierte Kopie implementieren + Ausschneiden + Einfügen für Daten (nicht Text oder CSV) zwischen Raster in einer WPF-Anwendung kopiert werden. Die Verwendung von Standard-ApplicationCommands und die Definition von CommandBinding funktionieren sehr gut, aber nur, wenn das DataGrid mindestens eine Datenzeile enthält und wenn es ausgewählt ist. Wenn keine Zeilen vorhanden sind oder der Fokus nicht auf einem davon liegt, sind alle Befehle deaktiviert.Implementieren Sie benutzerdefinierte Kopieren und Einfügen in WPF DataGrid, die funktioniert, wenn keine Zeilen darin sind
Um das Problem zu beheben, versuchte ich CommandManager.InvalidateRequerySuggested() und Focusable = True und/oder FocusManager.IsFocusScope = True auf dem DataGrid aufrufen, aber es scheint intern DataGrid als Ganzes ist nicht daran interessiert, mit Kopieren/Einfügen Operationen, nur die Zeilen sind erneut Abfragen Befehle CanExecute Zustand und Aufruf Execute entsprechend. Es ignoriert auch KeyBindings.
Wie DataGrid behandelt wird, Requerying ApplicationCommands behandeln?
finden Sie das Beispiel, an dem ich das Problem unten getestet:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DataGrid x:Name="TheGrid">
<DataGrid.Columns>
<DataGridTextColumn Header="Number" Binding="{Binding}"/>
</DataGrid.Columns>
<DataGrid.InputBindings>
<KeyBinding Key="A" Command="{x:Static ApplicationCommands.New}"/>
</DataGrid.InputBindings>
<DataGrid.CommandBindings>
<CommandBinding Command="{x:Static ApplicationCommands.Paste}" CanExecute="CanPaste" Executed="Paste"/>
<CommandBinding Command="{x:Static ApplicationCommands.Copy}" CanExecute="CanCopy" Executed="Copy"/>
<CommandBinding Command="{x:Static ApplicationCommands.New}" CanExecute="CanAddNew" Executed="AddNew"/>
</DataGrid.CommandBindings>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Command="{x:Static ApplicationCommands.Copy}" Header="Copy"/>
<MenuItem Command="{x:Static ApplicationCommands.Paste}" Header="Paste"/>
<MenuItem Command="{x:Static ApplicationCommands.New}" Header="New row"/>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</Window>
Und den Code hinter:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
namespace WpfApplication1
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
TheGrid.ItemsSource = numbers;
// Following line enables commands when row is selected
numbers.Add(0);
}
private void Copy(object sender, ExecutedRoutedEventArgs e)
{
Clipboard.SetData(DataFormats.Text, string.Join(",", numbers));
}
private void CanCopy(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = numbers.Count > 0;
}
private void CanPaste(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = numbers.Count > 0;
e.Handled = true;
}
private void Paste(object sender, ExecutedRoutedEventArgs e)
{
Close();
}
private void CanAddNew(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
e.Handled = true;
}
private void AddNew(object sender, ExecutedRoutedEventArgs e)
{
numbers.Add(numbers.Count);
}
private readonly ICollection<int> numbers = new ObservableCollection<int>();
}
}
bearbeiten
Der Code nur von Ayyappan Subramanian Lösung die beste Übereinstimmung mit der Anwendung, in der es verwendet wird. Schließlich, da ich bereits das Gitter erwerbe, weil es kundenspezifischen Polizisten hat y + Paste-Format zu arbeiten, habe ich einige Code, der sicherstellt, dass der Fokus innerhalb eines Gitters ist in 3 Fällen:
- Kontextmenü wird
- Benutzer klickt im Raster (leer) Bereich angezeigt, wenn es Kind Visuals ist kein Fokus
- (Unser App-spezifischer Fall) Der Benutzer klickt auf eine Grid-Navigation TreeView, die dann den Fokus auf das Grid bringt, damit Shortcuts sofort funktionieren.
Relevante Code:
public class MyDataGrid: DataGrid
{
protected override void OnContextMenuOpening(ContextMenuEventArgs e)
{
base.OnContextMenuOpening(e);
Focus();
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
if(e.ChangedButton == MouseButton.Left && !IsKeyboardFocusWithin)
{
Focus();
}
}
}
ich denke, es wegen der Linie sein könnte -> ** e.CanExecute = numbers.Count> 0; ** versuchen, die Linie in CanPaste Funktion Wechsel zu ** e.CanExecute = true; ** –
Es tut uns leid, aber keine Aktion ist aktiviert, ohne sich auf eine Zeile zu konzentrieren, einschließlich ApplicationCommands.New und es hat e.CanExecute immer auf True gesetzt. – too