data column c# wpf wpfdatagrid

c# - column - El desplazamiento del mouse no funciona en un visor de desplazamiento con un wpf datagrid y elementos de UI adicionales



wpf datagrid column (5)

Estoy tratando de averiguar cómo hacer que el mouse desplace el trabajo en una ventana de wpf con un scrollviewer y una red de datos dentro de ella. El código WPF y C # está debajo

<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid Grid.Row="0"> <Border Name="DataGridBorder" BorderThickness="2" Margin="1" CornerRadius="4" BorderBrush="#FF080757"> <dg:DataGrid AutoGenerateColumns="False" Name="ValuesDataGrid" BorderThickness="0" CanUserResizeColumns="True" FontWeight="Bold" HorizontalScrollBarVisibility="Auto" CanUserReorderColumns="False" IsReadOnly="True" IsTextSearchEnabled="True" AlternationCount="2" SelectionMode="Extended" GridLinesVisibility="All" HeadersVisibility="Column" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" CanUserSortColumns="False" RowDetailsVisibilityMode="Collapsed" SelectedIndex="0" RowStyle="{StaticResource CognitiDataGridRowStyle}" > <dg:DataGrid.Columns> <dg:DataGridTemplateColumn Header="Title" > <dg:DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" > <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=Name}" FontWeight="Normal" /> </StackPanel> </DataTemplate> </dg:DataGridTemplateColumn.CellTemplate> </dg:DataGridTemplateColumn> </dg:DataGrid.Columns> </dg:DataGrid> </Border> </Grid> <Button Grid.Row="1" Height="90" >hello world</Button> </Grid> </ScrollViewer>

y el código C # es el siguiente

public partial class Window1 : Window { public Window1() { InitializeComponent(); initialize(); } public void initialize() { ObservableCollection<MyObject> testList = new ObservableCollection<MyObject>(); for (int i = 0; i < 20; i++) { MyObject my = new MyObject("jack " + i); testList.Add(my); } ValuesDataGrid.ItemsSource = testList; } } public class MyObject { public string Name { get; set; } public MyObject(string name) { Name = name; } }

El problema al que me estoy enfrentando es que cuando uso el mouse para desplazarse, funciona bien cuando está sobre el botón, pero tan pronto como muevo el puntero del mouse sobre la cuadrícula e intento desplazarme, no sucede nada. Aunque puedo mover la barra de desplazamiento del scrollviewer directamente. Todavía soy un principiante de wpf, así que cualquier ayuda sobre cómo hacer que el mouse se desplace para trabajar sobre el datagrid sería apreciada. Supongo que debería haber una solución bastante fácil para esto, pero no he podido resolverlo


Creo que la solución de Dave es buena. Sin embargo, una recomendación que haría sería detectar el evento PreviewMouseWheel en el scrollviewer en lugar de en el datagrid. Si no lo hace, es posible que note algunas diferencias menores en función de si se está desplazando sobre la cuadrícula de datos o la barra de desplazamiento en sí. El razonamiento es que el scrollviewer manejará el desplazamiento cuando el mouse se desplace sobre la barra de desplazamiento, y el evento datagrid manejará el desplazamiento cuando esté sobre la datagrid. Por ejemplo, una rueda del mouse que se desplaza sobre la cuadrícula de datos podría llevarlo más abajo en su lista y luego lo haría cuando se encuentre sobre la barra de desplazamiento. Si lo detecta en el evento de vista previa de scrollviewer, todos usarán la misma medida al desplazarse. Además, si lo atrapa de esta manera, no necesitará nombrar el elemento scrollviewer, ya que no necesitará una referencia al objeto, ya que solo puede escribir cast el objeto remitente que se pasa al evento PreviewMouseWheel de scrollviewer. Por último, recomiendo marcar el evento manejado al final del evento, a menos que necesite capturarlo en un elemento más abajo de la jerarquía por alguna razón. Ejemplo a continuación:

private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) { ScrollViewer scv = (ScrollViewer)sender; scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta); e.Handled = true; }


Descubrí que ScrollViewer no se puede concatenar, lo que significa que si está concatenado como en su caso, la Cuadrícula comienza bajo la etiqueta ScrollViewer y en la Cuadrícula tenemos DataGrid y, en DataGrid, de nuevo, la propiedad ScrollViewer se ha establecido. es decir

HorizontalScrollBarVisibility="Auto".` <Border Grid.Row="3" Name="contentArea" BorderBrush="Black" BorderThickness="1" Margin="10,0,10,10"> <ScrollViewer CanContentScroll="True" IsDeferredScrollingEnabled="False" VerticalScrollBarVisibility="Auto"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="30"></RowDefinition> <RowDefinition Height="45"></RowDefinition> <RowDefinition Height="100*"></RowDefinition> <RowDefinition Height="105"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" FontWeight="Bold" Content="Vessel: " /> <TextBox Height="30" Width="300" Margin="70,0,0,0" HorizontalAlignment="Left" BorderThickness="1,1,1,1" IsReadOnly="True" Name="txtVessel"/> <Label Grid.Row="0" Grid.Column="2" Margin="0,0,185,0" HorizontalAlignment="Right" VerticalAlignment="Center" FontWeight="Bold" Content="Month:" /> <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="2" Margin="0,0,0,0" HorizontalAlignment="Right" > <ComboBox BorderThickness="2" HorizontalAlignment="Right" Name="CmbMonth" VerticalAlignment="Center" Width="90" /> <ComboBox BorderThickness="2" HorizontalAlignment="Right" Margin="5,0,0,0" Name="CmbYear" VerticalAlignment="Center" Width="90" /> </StackPanel> <Grid Grid.Row="1" Grid.ColumnSpan="2"> <Grid.RowDefinitions> <RowDefinition Height="45"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"></ColumnDefinition> <ColumnDefinition Width="220"></ColumnDefinition> <ColumnDefinition Width="80"></ColumnDefinition> <ColumnDefinition Width="80"></ColumnDefinition> <ColumnDefinition Width="80"></ColumnDefinition> <ColumnDefinition Width="80"></ColumnDefinition> <ColumnDefinition Width="120"></ColumnDefinition> <ColumnDefinition Width="120"></ColumnDefinition> <ColumnDefinition Width="140*"></ColumnDefinition> </Grid.ColumnDefinitions> <Border BorderBrush="Black" BorderThickness="0,1,1,1" Grid.Row="0" Grid.Column="0" ></Border> <Border BorderBrush="Black" BorderThickness="0,1,1,1" Grid.Row="0" Grid.Column="1" ></Border> <Border BorderBrush="Black" BorderThickness="0,1,1,1" Grid.Row="0" Grid.Column="2" ></Border> <Border BorderBrush="Black" BorderThickness="0,1,1,1" Grid.Row="0" Grid.Column="3" ></Border> <Border BorderBrush="Black" BorderThickness="0,1,1,1" Grid.Row="0" Grid.Column="4" ></Border> <Border BorderBrush="Black" BorderThickness="0,1,1,1" Grid.Row="0" Grid.Column="5" ></Border> <Border BorderBrush="Black" BorderThickness="0,1,1,1" Grid.Row="0" Grid.Column="6" ></Border> <Border BorderBrush="Black" BorderThickness="0,1,1,1" Grid.Row="0" Grid.Column="7" ></Border> <Border BorderBrush="Black" BorderThickness="0,1,1,1" Grid.Row="0" Grid.Column="8" ></Border> <Label Grid.Row="0" Grid.Column="1" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Content="Item" /> <Label Grid.Row="0" Grid.Column="2" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Content="Maker" /> <Label Grid.Row="0" Grid.Column="3" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Content="Model" /> <Label Grid.Row="0" Grid.Column="4" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Content=" Part No.&#x0a;Serial No." /> <Label Grid.Row="0" Grid.Column="5" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Content="Condition" /> <Label Grid.Row="0" Grid.Column="6" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Content=" Onboard&#x0a; Calibr/Test" /> <Label Grid.Row="0" Grid.Column="7" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Content=" Shore&#x0a; Callibration" /> <Label Grid.Row="0" Grid.Column="8" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Content="Remarks" /> </Grid> <Border Grid.Row="2" Grid.ColumnSpan="2" > <ScrollViewer Grid.Row="2" Grid.ColumnSpan="2" CanContentScroll="True" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" Name="ScrollViewer3" Margin="0,0,0,0"> <Grid Name="grdOnBoardCalibrationRecord" Margin="0,0,0,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"></ColumnDefinition> <ColumnDefinition Width="220"></ColumnDefinition> <ColumnDefinition Width="80"></ColumnDefinition> <ColumnDefinition Width="80"></ColumnDefinition> <ColumnDefinition Width="80"></ColumnDefinition> <ColumnDefinition Width="80"></ColumnDefinition> <ColumnDefinition Width="120"></ColumnDefinition> <ColumnDefinition Width="120"></ColumnDefinition> <ColumnDefinition Width="140*"></ColumnDefinition> </Grid.ColumnDefinitions> <Border Grid.Column="0" BorderThickness="1,0,1,1" BorderBrush="Black" Grid.RowSpan="26"></Border> <Border Grid.Column="1" BorderThickness="0,1,1,1" Grid.RowSpan="26"></Border> <Border Grid.Column="2" BorderThickness="0,1,1,1" Grid.RowSpan="26"></Border> <Border Grid.Column="3" BorderThickness="0,1,1,1" Grid.RowSpan="26"></Border> <Border Grid.Column="4" BorderThickness="0,1,1,1" Grid.RowSpan="26"></Border> <Border Grid.Column="5" BorderThickness="0,1,1,1" Grid.RowSpan="26"></Border> <Border Grid.Column="6" BorderThickness="0,1,1,1" Grid.RowSpan="26"></Border> <Border Grid.Column="7" BorderThickness="0,1,1,1" Grid.RowSpan="26"></Border> <Border Grid.Column="8" BorderThickness="0,1,1,1" Grid.RowSpan="26"></Border> </Grid> </ScrollViewer> </Border> <Grid Grid.Row="3" Grid.ColumnSpan="2"> <Grid.RowDefinitions> <RowDefinition Height="30"></RowDefinition> <RowDefinition Height="30"></RowDefinition> <RowDefinition Height="40"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <TextBox Grid.Row="0" Grid.Column="0" Height="30" Width="300" TextAlignment="Center" Background="Gray" IsReadOnly="True" Margin="0,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Bottom" BorderThickness="1,1,1,1" Name="txtChiefEngineer"/> <Label Grid.Row="1" Grid.Column="1" Margin="0,0,100,0" HorizontalAlignment="Right" VerticalAlignment="Center" FontWeight="Bold" Content="Chief Engineer" /> <StackPanel Orientation="Horizontal" Grid.Row="2" Margin="0,0,0,0" > <Label Name="lblonshorecomment" Content=" Shore Comment : " HorizontalAlignment="Center" Margin="5,0,0,0" FontWeight="Bold" VerticalAlignment="Center" FontFamily="Calibri" FontStyle="Normal" FontSize="14" ></Label> <TextBox BorderThickness="1" FontWeight="Normal" IsReadOnly="True" Height="44" Width="878" TextWrapping="Wrap" AcceptsReturn="True" HorizontalAlignment="left" Margin="0,0,0,0" Name="txtShoreComment" VerticalAlignment="Center" /> </StackPanel> </Grid> </Grid> </ScrollViewer> </Border>`


Intenté la solución de Don B y se soluciona el problema con el desplazamiento en una cuadrícula de datos bastante bien para los casos en los que no tiene otros controles internos desplazables.

En el caso de que el visor de desplazamiento tenga como hijos otros controles desplazables y una cuadrícula de datos, eso requiere que el evento no se marque como manejado al final del controlador de eventos para el visor de desplazamiento principal, por lo que también podría detectarse en Los controles internos desplazables, sin embargo, tienen el efecto secundario de que cuando el desplazamiento debe ocurrir solo en el control interno desplazable, también ocurre en el visor de desplazamiento principal.

Así que he actualizado la solución de Dave con la diferencia de cómo se encuentra el visor de desplazamiento para que no sea necesario saber el nombre del visualizador de desplazamiento:

private void DataGrid_PreviewMouseWheel(object sender, MouseWheelEventArgs e) { ScrollViewer scrollViewer = (((DependencyObject)sender).GetVisualParent<ScrollViewer>()); scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.Delta); }


Para habilitar la compatibilidad táctil, es posible que también desee establecer ScrollViewer.PanningMode en None en su DataGrid y establecer la misma propiedad en VerticalFirst u otro valor en su nivel superior ScrollViewer

Ejemplo

<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="5" PanningMode="VerticalFirst"> <DataGrid ScrollViewer.PanningMode="None" ItemsSource="{Binding Items}" /> </ScrollViewer>

Por supuesto, también use el evento PreviewMouseWheel como lo indican las respuestas de Don B para solucionar el problema del desplazamiento del mouse original.

private static void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) { var scrollViewer = (ScrollViewer)sender; scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.Delta); e.Handled = true; }

O, simplemente puede configurar la siguiente propiedad adjunta a su ScrollViewer

public class TopMouseScrollPriorityBehavior { public static bool GetTopMouseScrollPriority(ScrollViewer obj) { return (bool)obj.GetValue(TopMouseScrollPriorityProperty); } public static void SetTopMouseScrollPriority(ScrollViewer obj, bool value) { obj.SetValue(TopMouseScrollPriorityProperty, value); } public static readonly DependencyProperty TopMouseScrollPriorityProperty = DependencyProperty.RegisterAttached("TopMouseScrollPriority", typeof(bool), typeof(TopMouseScrollPriorityBehavior), new PropertyMetadata(false, OnPropertyChanged)); private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var scrollViewer = d as ScrollViewer; if (scrollViewer == null) throw new InvalidOperationException($"{nameof(TopMouseScrollPriorityBehavior)}.{nameof(TopMouseScrollPriorityProperty)} can only be applied to controls of type {nameof(ScrollViewer)}"); if (e.NewValue == e.OldValue) return; if ((bool)e.NewValue) scrollViewer.PreviewMouseWheel += ScrollViewer_PreviewMouseWheel; else scrollViewer.PreviewMouseWheel -= ScrollViewer_PreviewMouseWheel; } private static void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) { var scrollViewer = (ScrollViewer)sender; scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - e.Delta); e.Handled = true; } }

Uso

<ScrollViewer b:TopMouseScrollPriorityBehavior.TopMouseScrollPriority="True" VerticalScrollBarVisibility="Auto" Margin="5" PanningMode="VerticalFirst"> <DataGrid ScrollViewer.PanningMode="None" ItemsSource="{Binding Items}" /> </ScrollViewer>

Donde b: es el espacio de nombres que contiene este comportamiento

De esta manera, no se necesita ningún código subyacente y su aplicación es puramente MVVM


Supongo que el DataGrid no necesita desplazarse: establezca VerticalScrollBar = "None" en el DataGrid.

El DataGrid traga el evento de desplazamiento del mouse.

Lo que encontré es usar el evento PreviewMouseWheel para desplazar el contenedor que desea desplazar. Deberá asignar un nombre al scrollviewer para cambiar el desplazamiento vertical.

private void DataGrid_PreviewMouseWheel(object sender, MouseWheelEventArgs e) { scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset-e.Delta); }