31

問題:
全体が表示され ていない場合DataGrid(水平スクロール バーと垂直スクロール バーが表示されている場合)、部分的に表示されているセルの 1 つをクリックすると、グリッドが自動スクロールしてそのセルが表示されます。そうなってほしくありません。私は次のようにRequestBringIntoView、いじってみました:

private void DataGrid_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
    e.Handled = true;
}

しかし、それは何もしません。

私が試したこと:

  • 私のセルはカスタムUserControlsです。RequestBringIntoViewセルを構成するすべてのイベントハンドラーを配置して、イベントを処理しようとしましたが、それ自体UserControlsを処理するだけでは十分ではないのではないかと考えました。これはうまくいきませんでした。RequestBringIntoViewDataGrid
  • DataGridの内部をホストし、のイベントScrollViewerを処理しました。これは実際に機能し、自動スクロール動作を停止しますが、私の場合、 a の内部をホストすることはまったく望ましくないため、別の解決策を考え出す必要があります。ScrollViewerRequestBringIntoViewDataGridScrollViewer

この動作を止める方法がわかりません。何かアイデアはありますか?

4

9 に答える 9

32

でを定義しEventSetterDataGrid.RowStyle、行が表示されないようにするハンドラーを呼び出します。

XAML

<DataGrid>
    <DataGrid.RowStyle>
        <Style TargetType="{x:Type DataGridRow}">  
            <EventSetter Event="Control.RequestBringIntoView" Handler="DataGrid_Documents_RequestBringIntoView"  />
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

ハンドラ

private void DataGrid_Documents_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
    e.Handled = true;      
}
于 2011-04-04T12:36:03.017 に答える
11

最初の解決策が機能しなかったため、この問題を調べるのにさらに時間がかかりました。

しかし、ジョンの答えはほとんど良いものです。トリックは、それが処理されたことを示すために、ScrollViewer に到達する前に RequestBringIntoView イベントをキャッチすることです。

テンプレート全体を調整する必要がない場合は、次のコードを使用できます。

var scp = TreeHelper.FindVisualChild<ScrollContentPresenter>(this.datagrid);
scp.RequestBringIntoView += (s, e) => e.Handled = true;

ビジュアル ツリーの ScrollViewer のすぐ下にあるため、ScrollContentPresenter を使用します。

お役に立てれば !

于 2010-01-22T10:24:03.787 に答える
8

テンプレートを変更することで、DataGrid の内部 ScrollViewer にアクセスできます。通常、テンプレート内の分離コードにイベント ハンドラーを配置することはありませんが、テンプレートをインラインで宣言すると、イベント ハンドラーを DataGrid 自体にアタッチする場合と同じ方法で処理できます。これは、RequestBringIntoView イベントの ScrollViewer に追加されたハンドラーを含む、Blend から生成されたデフォルトのテンプレートです。

<ControlTemplate TargetType="{x:Type Controls:DataGrid}">
<Border SnapsToDevicePixels="True" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
    <ScrollViewer x:Name="DG_ScrollViewer" Focusable="False" RequestBringIntoView="DG_ScrollViewer_RequestBringIntoView">
        <ScrollViewer.Template>
            <ControlTemplate TargetType="{x:Type ScrollViewer}">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Button Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Controls:DataGrid}}}" Focusable="False">
                        <Button.Visibility>
                            <Binding Path="HeadersVisibility" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Controls:DataGrid}}">
                                <Binding.ConverterParameter>
                                    <Controls:DataGridHeadersVisibility>All</Controls:DataGridHeadersVisibility>
                                </Binding.ConverterParameter>
                            </Binding>
                        </Button.Visibility>
                        <Button.Template>
                            <ControlTemplate TargetType="{x:Type Button}">
                                <Grid>
                                    <Rectangle x:Name="Border" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" SnapsToDevicePixels="True"/>
                                    <Polygon x:Name="Arrow" Fill="Black" Stretch="Uniform" HorizontalAlignment="Right" Margin="8,8,3,3" VerticalAlignment="Bottom" Opacity="0.15" Points="0,10 10,10 10,0"/>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Stroke" TargetName="Border" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
                                    </Trigger>
                                    <Trigger Property="IsPressed" Value="True">
                                        <Setter Property="Fill" TargetName="Border" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
                                    </Trigger>
                                    <Trigger Property="IsEnabled" Value="False">
                                        <Setter Property="Visibility" TargetName="Arrow" Value="Collapsed"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Button.Template>
                        <Button.Command>
                            <RoutedCommand/>
                        </Button.Command>
                    </Button>
                    <Custom:DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1">
                        <Custom:DataGridColumnHeadersPresenter.Visibility>
                            <Binding Path="HeadersVisibility" RelativeSource="{RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Controls:DataGrid}}">
                                <Binding.ConverterParameter>
                                    <Controls:DataGridHeadersVisibility>Column</Controls:DataGridHeadersVisibility>
                                </Binding.ConverterParameter>
                            </Binding>
                        </Custom:DataGridColumnHeadersPresenter.Visibility>
                    </Custom:DataGridColumnHeadersPresenter>
                    <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Grid.ColumnSpan="2" Grid.Row="1" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False"/>
                    <ScrollBar x:Name="PART_VerticalScrollBar" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Grid.Column="2" Grid.Row="1" Maximum="{TemplateBinding ScrollableHeight}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" Orientation="Vertical" ViewportSize="{TemplateBinding ViewportHeight}"/>
                    <Grid Grid.Column="1" Grid.Row="2">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type Controls:DataGrid}}}"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <ScrollBar x:Name="PART_HorizontalScrollBar" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" Orientation="Horizontal" ViewportSize="{TemplateBinding ViewportWidth}"/>
                    </Grid>
                </Grid>
            </ControlTemplate>
        </ScrollViewer.Template>
        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    </ScrollViewer>
</Border>

于 2010-01-21T20:48:15.083 に答える
6

私は Rumit と同じ問題を抱えていましたが、解決策/ハックを見つけました。

マウス クリックと矢印キーを区別する方法を見つけることができれば、それに応じて e.Handled を設定できると考えました。

いくつかの実験の後、マウスまたは矢印キーに応じて e.OriginalSource が変化することがわかりました。マウス クリックの場合、RequestBringIntoView のハンドラーが 1 回呼び出され、e.OriginalSource は DataGridCell 型でした。矢印キーの場合、ハンドラーは 2 回呼び出され、e.OriginalSource の型は DataGridRow、次に DataGridCell です。

私のハンドラーのコードは次のとおりです。

e.Handled = (e.OriginalSource is DataGridCell);

これは少しハックのように思えますが、私にとってはうまく機能します。

于 2016-09-08T20:34:38.160 に答える
5

私は同じ問題を抱えていて、ヤンの答えが役に立ちました。唯一欠けていたのは、Loaded イベントが発生した後にのみ ScrollContentPresenter が見つかるということでした。グリッドを自動的にスクロールするかどうかを制御する AutoScroll プロパティを追加して、DataGrid から継承した拡張 DataGrid クラスを作成しました。

クラスは次のとおりです。

using System.Windows;
using System.Windows.Controls;
using Microsoft.Windows.Controls;

namespace Bartosz.Wojtowicz.Wpf
{
    public class ExtendedDataGrid : DataGrid
    {
        public bool AutoScroll { get; set; }

        public ExtendedDataGrid()
        {
            AutoScroll = true;
            Loaded += OnLoaded;
        }

        private void OnLoaded(object sender, RoutedEventArgs eventArgs)
        {
            if (!AutoScroll)
            {
                ScrollContentPresenter scp = DataGridHelper.GetVisualChild<ScrollContentPresenter>(this);
                if (scp != null) scp.RequestBringIntoView += OnRequestBringIntoView;
            }
        }

        private static void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
        {
            e.Handled = true;
        }
    }
}

そして、これを使用する方法は次のとおりです。

   <local:ExtendedDataGrid AutoScroll="False">
        <!-- your grid definition -->
   </local:ExtendedDataGrid>
于 2011-11-02T15:03:59.803 に答える
1

これが機能しているかどうかはわかりませんが、Reflectorを使用してDataGridのソースコードで行われた調査に基づいたアイデアを次に示します。

1/DataGridCellsPanelを継承するクラスを作成します。これは、セルを配置するためにDataGridによって内部的に使用されるパネルです。

2 / BringIndexIntoViewメソッドを空のメソッドでオーバーライドします(基本メソッドを呼び出さずに)

3/XAMLでItemsPanelTemplateプロパティを設定します。

<tk:DataGrid>
    <tk:DataGrid.ItemsPanel>
        <ItemsPanelTemplate>
            <local:DataGridCellsPanelNoAutoScroll />
        </ItemsPanelTemplate>
    </tk:DataGrid.ItemsPanel>
</tk:DataGrid>

MouseDownイベントが発生すると、ある時点でパネルのBringIndexIntoViewメソッドが呼び出されて自動スクロールが実行されるようです。それをno-opに置き換えると、うまくいくかもしれません。

このソリューションをテストする時間がありませんでした。機能しているかどうかをお知らせください。

于 2010-01-14T15:40:35.507 に答える