2011-07-29 2 views
2

Dans mon application, j'ai un canevas enveloppé dans un ScrollViewer (Canvas est plus grand que la taille de l'écran). Sur cette toile j'ai placé d'autres contrôles. L'un des éléments du canevas contient un DataGrid virtualisé (avec plus de 2 000 lignes ... donc le défilement est également impliqué). Maintenant, j'ai une fonction qui sélectionne une ligne dans le DataGrid en fonction de certaines valeurs de l'élément row (déclenché automatiquement). Lorsque la ligne est sélectionnée, j'appelleScrollIntoView avec ScrollViewer imbriqué

uxDataGrid.ScrollIntoView(uxDataGrid.SelectedItems[0]); 

ce qui fonctionne parfaitement bien. En fait, il travaille pour le bien. Ce que je veux, c'est que l'élément dans le DataGrid est sélectionné, puis le DataGrid doit défiler vers la position correcte. Mais aussi mon scrolviewer Canvas est en quelque sorte ramasser cette demande et fait défiler là aussi.

J'ai déjà essayé d'intercepter le ScrollChangedEvent et de définir l'indicateur géré. Mais ça ne fonctionne pas.

qustions:

1) Comment puis-je limiter l'effet de l'appel ScrollIntoView au contrôle de l'utilisateur local.

2) Si ce n'est pas possible, comment puis-je faire le défilement par moi-même? Je devrais calculer le décalage vertical pour le scrollviewer, mais puisqu'il est virtualisé je n'ai aucune idée comment je peux trouver la taille de rangée?

Des suggestions?

J'ai ajouté un échantillon rapide pour illustrer la configuration principale. Lorsque vous appuyez sur l'un des boutons, je veux seulement que le DataGrid défile, pas le ScrollViewer qui continue le canevas.

<Window x:Class="ScrollTest.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"> 
<DockPanel> 
    <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal"> 
     <Button Click="Button1_Click">Scroll to 1</Button> 
     <Button Click="Button100_Click">Scroll to 100</Button> 
     <Button Click="Button200_Click">Scroll to 200</Button> 
    </StackPanel> 
    <ScrollViewer> 
     <Canvas Width="5000" Height="5000"> 
      <DataGrid Name="uxDataGrid" ItemsSource="{Binding TestItems}" Width="500" Height="500"></DataGrid> 
     </Canvas> 
    </ScrollViewer> 
</DockPanel> 

public class TestItem 
{ 
    public TestItem(int id) 
    { 
     Property1 = id.ToString(); 
     Property2 = "B"; 
    } 
    public string Property1 { get; set; } 
    public string Property2 { get; set; } 
} 
/// <summary> 
/// Interaktionslogik für MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    public IList<TestItem> TestItems { get; set; } 
    public MainWindow() 
    { 
     TestItems = new List<TestItem>(); 
     for (int i = 0; i < 300; i++) 
     { 
      TestItems.Add(new TestItem(i)); 
     } 

     InitializeComponent(); 
     DataContext = this; 
    } 


    private void Button1_Click(object sender, RoutedEventArgs e) 
    { 
     uxDataGrid.ScrollIntoView(TestItems[0]); 
    } 
    private void Button100_Click(object sender, RoutedEventArgs e) 
    { 
     uxDataGrid.ScrollIntoView(TestItems[99]); 
    } 
    private void Button200_Click(object sender, RoutedEventArgs e) 
    { 
     uxDataGrid.ScrollIntoView(TestItems[199]); 
    } 
} 

Répondre

5

Ok ... après quelques recherches, j'ai trouvé l'événement correct: Il est appelé RequestBringIntoViewEvent. Lors de l'interception de celui-ci, il fonctionne comme prévu:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     ... 
     uxDataGrid.AddHandler(RequestBringIntoViewEvent, new RoutedEventHandler(HandleRequestBringIntoViewEvent)); 
    } 

    private static void HandleRequestBringIntoViewEvent(object sender, RoutedEventArgs e) 
    { 
     e.Handled = true; 
    } 
    ... 
} 
+0

Pourriez-vous indiquer votre réponse comme solution? –

+0

Pas encore ... Je dois attendre 2 jours – harri

+0

merci. Cela fonctionne très bien !!! –