[ad_1]
皆さん、こんにちは:
私はドラッグアンドドロップの例に従っています:
https://www.c-sharpcorner.com/UploadFile/raj1979/drag-and-drop-datagrid-row-in-wpf/ しかし、スクロールバー (水平または垂直) を使用すると問題が発生することがあります。
例のデータではなく、多数の列と多数の行を持つテーブルのデータを使用しています。
コード例では、GetMouseTargetRow プロシージャで、スクロールバー ボタン (水平または垂直) を移動しているときに、データグリッドのセル領域の外側をクリックしているかどうかがわかります。
しかし、列がデータグリッド領域の幅を超えている場合、GetMouseTargetRow プロシージャは、スクロールバーに触れたことを認識しないため、false を返します。 すべての列を小さくして、データ グリッドの幅よりも少ない領域を占めるようにすると、すべて正常に機能します。
水平スクロールバーを移動すると、同じことが起こります。これは、データグリッドがクラッシュして列の幅を調整できない場合があるためです。
私のテストとの唯一の違いは、私の XAML コードでは、データグリッドで d:LayoutOverrides=”Width” を使用していないことです。 それは問題を説明していますか? LayoutOverride は何に使用されますか?
助けてくれてありがとう。
私が試したこと:
これは私の最初の WPF データグリッド テストです。
解決策 2
簡単な解決策へのリンクを提供したかったのです。 これは不可能であることが判明しました。
そのため、次のリンクから解決策を採用しました。
* WPF で DataGrid 行をドラッグ アンド ドロップする[^] = 最初の試み – ドラッグ アンド ドロップの良い解決策ではありません!
* WPF チュートリアル | ドラッグドロップ[^] = Drag’n’Drop を実装するより良い方法ですが、コントロールが間違っています
* WPF: ドラッグ & ドロップ中にコントロールの内容をスクロールする[^] =例のない実用的な解決策
1. ScrollOnDragOverBehavior
上記のリンクから変更する必要はありませんでしたので、そこからコードを取得してください。
2. ObservableObject
をラッピングするクラス INotifyPropertyChanged
public abstract class ObservableObject : INotifyPropertyChanged { public void Set<TValue>(ref TValue field, TValue newValue, [CallerMemberName] string propertyName = "") { if (!EqualityComparer<TValue>.Default.Equals(field, default) && field!.Equals(newValue)) return; field = newValue; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler? PropertyChanged; }
3. Employee
データ・モデル:
public class EmployeeModel : ObservableObject { private int empNo; private string empName; private int salary; public int EmpNo { get => empNo; set => Set(ref empNo, value); } public string EmpName { get => empName; set => Set(ref empName, value); } public int Salary { get => salary; set => Set(ref salary, value); } }
4. MainWindow
コードビハインド
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); InitData(); DataGrid.PreviewMouseLeftButtonDown += OnPreviewMouseLeftButtonDown; DataGrid.MouseMove += OnMouseMove; DataGrid.DragEnter += OnDragEnter; DataGrid.Drop += OnDrop; } private void InitData() { Employees.Add(new() { EmpNo = 101, EmpName = "Yudhistir", Salary = 56000 }); Employees.Add(new() { EmpNo = 102, EmpName = "Bhim", Salary = 36000 }); Employees.Add(new() { EmpNo = 103, EmpName = "Arjun", Salary = 45000 }); Employees.Add(new() { EmpNo = 104, EmpName = "Sahedev", Salary = 24000 }); Employees.Add(new() { EmpNo = 105, EmpName = "Nakul", Salary = 22000 }); Employees.Add(new() { EmpNo = 101, EmpName = "Yudhistir", Salary = 56000 }); Employees.Add(new() { EmpNo = 102, EmpName = "Bhim", Salary = 36000 }); Employees.Add(new() { EmpNo = 103, EmpName = "Arjun", Salary = 45000 }); Employees.Add(new() { EmpNo = 104, EmpName = "Sahedev", Salary = 24000 }); Employees.Add(new() { EmpNo = 105, EmpName = "Nakul", Salary = 22000 }); Employees.Add(new() { EmpNo = 101, EmpName = "Yudhistir", Salary = 56000 }); Employees.Add(new() { EmpNo = 102, EmpName = "Bhim", Salary = 36000 }); Employees.Add(new() { EmpNo = 103, EmpName = "Arjun", Salary = 45000 }); Employees.Add(new() { EmpNo = 104, EmpName = "Sahedev", Salary = 24000 }); Employees.Add(new() { EmpNo = 105, EmpName = "Nakul", Salary = 22000 }); Employees.Add(new() { EmpNo = 101, EmpName = "Yudhistir", Salary = 56000 }); Employees.Add(new() { EmpNo = 102, EmpName = "Bhim", Salary = 36000 }); Employees.Add(new() { EmpNo = 103, EmpName = "Arjun", Salary = 45000 }); Employees.Add(new() { EmpNo = 104, EmpName = "Sahedev", Salary = 24000 }); Employees.Add(new() { EmpNo = 105, EmpName = "Nakul", Salary = 22000 }); Employees.Add(new() { EmpNo = 101, EmpName = "Yudhistir", Salary = 56000 }); Employees.Add(new() { EmpNo = 102, EmpName = "Bhim", Salary = 36000 }); Employees.Add(new() { EmpNo = 103, EmpName = "Arjun", Salary = 45000 }); Employees.Add(new() { EmpNo = 104, EmpName = "Sahedev", Salary = 24000 }); Employees.Add(new() { EmpNo = 105, EmpName = "Nakul", Salary = 22000 }); Employees.Add(new() { EmpNo = 101, EmpName = "Yudhistir", Salary = 56000 }); Employees.Add(new() { EmpNo = 102, EmpName = "Bhim", Salary = 36000 }); Employees.Add(new() { EmpNo = 103, EmpName = "Arjun", Salary = 45000 }); Employees.Add(new() { EmpNo = 104, EmpName = "Sahedev", Salary = 24000 }); Employees.Add(new() { EmpNo = 105, EmpName = "Nakul", Salary = 22000 }); Employees.Add(new() { EmpNo = 101, EmpName = "Yudhistir", Salary = 56000 }); Employees.Add(new() { EmpNo = 102, EmpName = "Bhim", Salary = 36000 }); Employees.Add(new() { EmpNo = 103, EmpName = "Arjun", Salary = 45000 }); Employees.Add(new() { EmpNo = 104, EmpName = "Sahedev", Salary = 24000 }); Employees.Add(new() { EmpNo = 105, EmpName = "Nakul", Salary = 22000 }); } public ObservableCollection<EmployeeModel> Employees { get; set; } = new(); private Point startPoint; // Store the mouse position private void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) => startPoint = e.GetPosition(null); private void OnMouseMove(object sender, MouseEventArgs e) { // Get the current mouse position Point mousePos = e.GetPosition(null); Vector diff = startPoint - mousePos; if (e.LeftButton == MouseButtonState.Pressed && (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)) { // Get the dragged DataGridRow DataGridRow row = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource); // Find the data behind the DataGridRow EmployeeModel employee = (EmployeeModel)DataGrid.ItemContainerGenerator.ItemFromContainer(row); // Initialize the drag & drop operation DataObject dragDataObject = new DataObject("DataRow", employee); DragDrop.DoDragDrop(row, dragDataObject, DragDropEffects.Move); } } private void OnDragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent("DataRow") && sender != e.Source) return; e.Effects = DragDropEffects.None; } private void OnDrop(object sender, DragEventArgs e) { if (!e.Data.GetDataPresent("DataRow")) return; EmployeeModel source = e.Data.GetData("DataRow") as EmployeeModel; // Get the destination DataGridRow var row = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource); // Find the data behind the DataGridRow var destination = (EmployeeModel)DataGrid.ItemContainerGenerator.ItemFromContainer(row); // Move the EmployeeModel in the collection Employees.RemoveAt(Employees.IndexOf(source)); Employees.Insert(Employees.IndexOf(destination) + 1, source); } // Helper to search up the VisualTree private static T FindAncestor<T>(DependencyObject current) where T : DependencyObject { do { if( current is T dependencyObject ) return dependencyObject; current = VisualTreeHelper.GetParent(current); } while (current != null); return null; } }
5. MainWindow
XAML/UI
<Window x:Class="WpfScrollOnDragOverBehavior.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfScrollOnDragOverBehavior" mc:Ignorable="d" x:Name="Window" Title="MainWindow" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <TextBox HorizontalAlignment="Stretch" Margin="10" Text="EmployeeModel Information" TextAlignment="Center" FontFamily="SimSun" FontSize="28" /> <DataGrid x:Name="DataGrid" Grid.Row="1" ItemsSource="{Binding ElementName=Window, Path=Employees}" AutoGenerateColumns="False" HorizontalAlignment="Stretch" Margin="10" ColumnWidth="*" SelectionMode="Extended" AllowDrop="True" local:ScrollOnDragOverBehavior.IsScrollOnDragOverEnabled="True"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding EmpNo}" Header="ProductId"></DataGridTextColumn> <DataGridTextColumn Binding="{Binding EmpName}" Header="ProductName"></DataGridTextColumn> <DataGridTextColumn Binding="{Binding Salary}" Header="ProductPrice"></DataGridTextColumn> </DataGrid.Columns> </DataGrid> </Grid> </Window>
をドラッグすると DataGridRow
の端に DataGrid
、 DataGrid
スクロールします。 ドロップすると、ドラッグ中のアイテムがドロップします 後 対象の行。
ボーナス
マウスカーソルの横にドラッグされている行を表示したい場合は、Josh の優れた記事をご覧ください。 WPF ListView で項目をドラッグ アンド ドロップする[^] – この質問の範囲外なので、これはあなたに任せます。
[ad_2]
コメント