2011-07-29 22 views
2

私のアプリケーションでは、ScrollViewerでキャンバスをラップしています(キャンバスは画面サイズより大きくなります)。このキャンバスで私は他のコントロールを配置しました。キャンバス上の要素の1つに、仮想化されたDataGrid(2000以上の行が含まれているため、スクロールも同様に関わっています)が含まれています。今私は、行要素のいくつかの値(automaticalyをトリガ)に基づいてDataGridの行を選択する関数を持っています。行が選択されると、私は入れ子のScrollViewerを使用したScrollIntoView

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

という名前で何か問題なく動作しています。実際、それは良い方法に働いています。私が欲しいのは、DataGridの要素が選択されてから、DataGridが正しい位置にスクロールすることです。しかし、私のキャンバススクロールビューアも何とかこのリクエストを受け取り、そこでスクロールしています。

私はすでにScrollChangedEventをインターセプトし、処理済みのフラグを設定しようとしました。しかし、それは動作していません。

Qustions:

1)どのように私は、ローカルユーザーコントロールへのscrollIntoViewコールの影響を制限することができます。

2)それができない場合は、どうすれば自分でスクロールできますか? scrollviewerの垂直オフセットを計算する必要がありますが、仮想化されているので、どのように行の高さを見つけることができないのでしょうか?

提案がありますか?

私は、プリンシパルセットアップを示すためのクイックサンプルを追加しました。ボタンの1つを押すと、DataGridだけをスクロールするだけで、スクロールビューアはキャンバスをコントロールしません。

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

答えて

5

[OK]を...いくつかの研究の後、私は正しいイベントを見つけました:これはRequestBringIntoViewEventと呼ばれています。それを傍受すると、期待どおりに動作しています:

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

回答を解決策としてマークできますか? –

+0

まだ... 2日待たなければならない – harri

+0

ありがとう。それは素晴らしい作品! –

関連する問題