2010-01-13 7 views

Antwort

3

Dies wird nicht im DataGrid im Toolkit unterstützt, und es sieht wie won't be supported aus, wenn das DataGrid mit .NET 4 entweder geliefert wird. Ein weiterer Grund, warum diese Steuerung nicht für den produktiven Einsatz bereit ist. Ich würde mit einer dieser Optionen gehen:

  1. Rollen Ihr eigenes Raster mit Listview/Gridview
  2. Ändern Sie den Quellcode des Datagrid in dem Toolkit (es sollte nicht allzu schwer sein, da erweiterte Auswahl bereits unterstützt wird ?)
  3. Geben Sie für jede der kommerziellen WPF Datagrid zur Verfügung (sie in der Regel große Menge an nützlichen Funktionen hinzufügen)

ich bin damit einverstanden, dass das Datagrid diese unterstützen sollte und ich denke, Sie file a bug/suggestion für diese ohnehin sollte. Vielleicht ist es nicht zu spät, um es in .NET 4 zu erhalten .. :)

3

Sie diese einfache Abhilfe, ohne dass Modifizieren/vererben DataGrid Steuerung versuchen kann Ereignisvorschau Maus nach unten durch die Handhabung wie folgt:

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); 
} 

Die Methode TryFindFromPoint von blog post by Philipp Sumi wird verwendet, um die DataGridRow Instanz von dem Punkt zu erhalten, auf den Sie geklickt haben.

Wenn Sie ModifierKeys überprüfen, können Sie weiterhin Strg und Shift als Standardverhalten beibehalten.

Nur ein Nachteil dieser Methode besteht darin, dass Sie nicht klicken und ziehen können, um die Bereichsauswahl wie ursprünglich ausgeführt durchzuführen.

10

Ich erstellte eine Anwendung mit einer ähnlichen Anforderung, die für Touchscreen und Desktop funktionieren würde. Nach einiger Zeit scheint die Lösung, die ich gefunden habe, sauberer zu sein. im Designer ich die folgenden Ereignis Setter Datagrid hinzugefügt:

<DataGrid.RowStyle> 
    <Style TargetType="DataGridRow" > 
    <EventSetter Event="MouseEnter" Handler="MouseEnterHandler"></EventSetter> 
    <EventSetter Event="PreviewMouseDown" Handler="PreviewMouseDownHandler"></EventSetter> 
    </Style> 
</DataGrid.RowStyle> 

Dann in der Code-Behind, behandelt ich die Ereignisse als:

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; 
    } 
} 

Hier ist der Code für die Hilfsmethode GetVisualParentByType:

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; 
} 

Hoffe, es hilft auch jemand anderen.

0

auf einem frühen Artikel Basierend, ich schrieb ein ("like") MVVM Code:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 

Der relevante Teil der Ansicht::

Erstens diese zu Ihrer Hauptansicht hinzufügen

 <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> 

Mehr Informationen über EventToCommandBehavior: here

Auf diese Weise müssen Sie Ihr Ansichtsmodell diese Befehle implementieren:

//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; 
        } 
       }     
      }); 
     } 
    } 

schließlich ein Verfahren implementieren (irgendwo in Model) die Zeile (n) zu finden.

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; 
    } 

Diese Lösung funktioniert für mich perfekt, so hoffe ich es für Sie zu helfen.

Verwandte Themen