La cuadrícula de datos WPF tiene dos modos de selección, Single o Extended. El WPF ListView tiene un tercero - Múltiple. Este modo le permite hacer clic y seleccionar varias filas sin presionar CTRL o Shift. ¿Alguien sabe cómo hacer esto para la cuadrícula de datos?WPF Datagrid Selección múltiple sin CTRL o espacio
Respuesta
Esto no es compatible con DataGrid en el kit de herramientas, y se ve como won't be supported cuando el DataGrid se envía con .NET 4 tampoco. Otra razón más por la cual este control no está listo para el uso de producción. Me gustaría ir con una de estas opciones:
- rodar su propia cuadrícula con ListView/GridView
- modificar el código fuente de la cuadrícula de datos en la caja de herramientas (que no debería ser demasiado difícil ya que la selección extendida ya está soportada ?)
- Busque cualquiera de las DataGrids comerciales WPF disponible (por lo general, se suman gran cantidad de funcionalidades útiles)
Estoy de acuerdo que la cuadrícula de datos debe apoyar esto y creo que deberías file a bug/suggestion para esto de todos modos. Tal vez no es demasiado tarde para entrar en .NET 4 .. :)
Puede probar esta sencilla solución sin tener que modificar/heredar DataGrid
de control por el manejo vista previa del ratón evento como sigue:
TheDataGrid.PreviewMouseLeftButtonDown +=
new MouseButtonEventHandler(TheDataGrid_PreviewMouseLeftButtonDown);
void TheDataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// get the DataGridRow at the clicked point
var o = TryFindFromPoint<DataGridRow>(TheDataGrid, e.GetPosition(TheDataGrid));
// only handle this when Ctrl or Shift not pressed
ModifierKeys mods = Keyboard.PrimaryDevice.Modifiers;
if (o != null && ((int)(mods & ModifierKeys.Control) == 0 &&
(int)(mods & ModifierKeys.Shift) == 0))
{
o.IsSelected = !o.IsSelected;
e.Handled = true;
}
}
public static T TryFindFromPoint<T>(UIElement reference, Point point)
where T:DependencyObject
{
DependencyObject element = reference.InputHitTest(point) as DependencyObject;
if (element == null)
return null;
else if (element is T)
return (T)element;
else return TryFindParent<T>(element);
}
El método TryFindFromPoint
, de blog post by Philipp Sumi, se utiliza para obtener la instancia DataGridRow
del punto en el que hizo clic.
Al marcar ModifierKeys
, aún puede mantener Ctrl y Shift como comportamiento predeterminado.
Solo un inconveniente de este método es que no puede hacer clic y arrastrar para realizar la selección de rango como originalmente.
Estaba creando una aplicación con un requisito similar que funcionaría tanto para la pantalla táctil como para el escritorio. Después de pasar algún tiempo en él, la solución que se me ocurrió parece más limpia. En el diseñador, que añaden los siguientes emisores de eventos a la cuadrícula de datos:
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<EventSetter Event="MouseEnter" Handler="MouseEnterHandler"></EventSetter>
<EventSetter Event="PreviewMouseDown" Handler="PreviewMouseDownHandler"></EventSetter>
</Style>
</DataGrid.RowStyle>
Luego, en el código subyacente, que manejé los eventos como:
private void PreviewMouseDownHandler(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
DataGridRow row = Utility.GetVisualParentByType(
(FrameworkElement)e.OriginalSource, typeof(DataGridRow)) as DataGridRow;
row.IsSelected = !row.IsSelected;
e.Handled = true;
}
}
private void MouseEnterHandler(object sender, MouseEventArgs e)
{
if (e.OriginalSource is DataGridRow && e.LeftButton == MouseButtonState.Pressed)
{
DataGridRow row = e.OriginalSource as DataGridRow;
row.IsSelected = !row.IsSelected;
e.Handled = true;
}
}
Aquí está el código para el GetVisualParentByType método de ayuda:
public static DependencyObject GetVisualParentByType(DependencyObject startObject, Type type)
{
DependencyObject parent = startObject;
while (parent != null)
{
if (type.IsInstanceOfType(parent))
break;
else
parent = VisualTreeHelper.GetParent(parent);
}
return parent;
}
Espero que ayude a alguien más también.
Basado en un artículo anterior, escribí una ("me gusta") Código de MVVM:
En primer lugar agregar esto a su vista principal:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
La parte pertinente de Vista:
<DataGrid
Style="{StaticResource DataGridStyle}"
ItemsSource="{Binding Results}"
SelectionUnit="FullRow"
SnapsToDevicePixels="True"
SelectionMode="Extended"> <!--You can change selection mode with converter. It will work (i tested it.)-->
<i:Interaction.Behaviors>
<utils:EventToCommandBehavior Command="{Binding TouchCommand}"
Event="PreviewTouchDown"
PassArguments="True"></utils:EventToCommandBehavior>
<utils:EventToCommandBehavior Command="{Binding MouseCommand}"
Event="PreviewMouseDown"
PassArguments="True"></utils:EventToCommandBehavior>
</i:Interaction.Behaviors>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsSelected"<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A="50" R="0" G="0" B="0" />
</SolidColorBrush.Color>
</SolidColorBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<!-- your columns -->
</DataGrid.Columns>
</DataGrid>
Más información sobre EventToCommandBehavior: here
De esta manera, el modelo de vista hay que poner en práctica estos comandos:
//i skipped the TouchCommand definition because MouseCommand runs for touch on screen too.
public RelayCommand<MouseButtonEventArgs> MouseCommand
{
get
{
return new RelayCommand<MouseButtonEventArgs>((e)=> {
if (e.LeftButton == MouseButtonState.Pressed)
{
//call this function from your utils/models
var row = FindTemplatedParentByVisualParent<DataGridRow>((FrameworkElement)e.OriginalSource,typeof(ICommandSource));
//add ICommanSource to parameters. (if actual cell contains button instead of data.) Its optional.
if(row!=null)
{
row.IsSelected = !row.IsSelected;
e.Handled = true;
}
}
});
}
}
Finalmente implementar un método (en algún lugar de Modelo) para encontrar la fila (s).
public static T FindTemplatedParentByVisualParent<T>(FrameworkElement element,Type exceptionType = null) where T : class
{
if (element != null && (exceptionType == null || element.TemplatedParent == null || (exceptionType != null && element.TemplatedParent !=null && !exceptionType.IsAssignableFrom(element.TemplatedParent.GetType()))))
{
Type type = typeof(T);
if (type.IsInstanceOfType(element.TemplatedParent))
{
return (element.TemplatedParent as T);
}
else
{
return FindTemplatedParentByVisualParent<T>((FrameworkElement)VisualTreeHelper.GetParent(element));
}
}
else
return null;
}
Esta solución funciona perfectamente para mí, así que espero que te sirva también.
- 1. WPF DataGrid enlace múltiple selectivo
- 2. WPF XAML: ¿Cómo deshabilitar la selección múltiple en un DataGrid?
- 3. WPF TreeView con selección múltiple
- 4. WPF DataGrid: ¿Cómo borrar la selección programáticamente?
- 5. WPF Toolkit Datagrid: ¿cómo desactivas la selección?
- 6. evitar la selección de múltiples filas en WPF DataGrid
- 7. Selección múltiple en Vim
- 8. VirtualizingStackPanel + MVVM + selección múltiple
- 9. WPF DataGrid Columna Ancho
- 10. Estilo WPF DataGrid-Silverlight DataGrid?
- 11. ELEGIR elemento en el estilo de visualización de selección múltiple sin permitir selección múltiple
- 12. WPF DataGrid SelectedItem
- 13. WPF DataGrid AutoSize Issue
- 14. WPF DataGrid Ocultar filaDetalles o anular la selección de la fila
- 15. GWT CellList Haga clic para alternar la selección (Selección múltiple)
- 16. Spinner de selección múltiple
- 17. Selección múltiple en TreeView
- 18. WPF DataGrid: ¿Reordenar filas?
- 19. WPF DataGrid pegar
- 20. Filtro WPF DataGrid
- 21. WPF datagrid con MVVM
- 22. WPF Toolkit DataGrid Multi-Select: ¿Cómo obtener Selected Items out?
- 23. lista de WPF arrastre sin anular la selección
- 24. Jquery selección múltiple
- 25. ¿Deshabilitar selección múltiple?
- 26. OpenFileDialog selección múltiple problema
- 27. Selección múltiple de JcomboBox
- 28. UITableView Selección múltiple
- 29. Wpf DataGrid problema
- 30. WPF Datagrid Performance