に役立ちます願っています。
DataGrid
は、2つの異なる方法を使用しています。
まず:行ヘッダ
これは単純化されたTemplate
DataGridRow
ためのものです:
<Border x:Name="DGR_Border" ... >
<SelectiveScrollingGrid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DataGridRowHeader Grid.RowSpan="2"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" ... />
<DataGridCellsPresenter Grid.Column="1" ... />
<DataGridDetailsPresenter Grid.Column="1" Grid.Row="1"
SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
Path=AreRowDetailsFrozen, Converter={x:Static DataGrid.RowDetailsScrollingConverter},
ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}}" ... />
</SelectiveScrollingGrid>
</Border>
あなたがDataGrid
を見ることができるようにして行ヘッダを保持するためにSelectiveScrollingOrientation
添付プロパティを使用していますポジション。このプロパティが設定されている(または変更されている)場合、親にバインドされたTranslateTransform
が作成されます。ScrollViewer
要素のオフセット。詳細はsource codeを参照してください。
第二:FrozenColumns
このようなものはDataGridCellsPanel
ArrangeOverride()
で行われます。これは、プライベートArrangeState
クラスを使用して、 "複数の子のアレンジの間の状態を維持する"。
private class ArrangeState
{
public ArrangeState()
{
FrozenColumnCount = 0;
ChildHeight = 0.0;
NextFrozenCellStart = 0.0;
NextNonFrozenCellStart = 0.0;
ViewportStartX = 0.0;
DataGridHorizontalScrollStartX = 0.0;
OldClippedChild = null;
NewClippedChild = null;
}
public int FrozenColumnCount { get; set; }
public double ChildHeight { get; set; }
public double NextFrozenCellStart { get; set; }
public double NextNonFrozenCellStart { get; set; }
public double ViewportStartX { get; set; }
public double DataGridHorizontalScrollStartX { get; set; }
public UIElement OldClippedChild { get; set; }
public UIElement NewClippedChild { get; set; }
}
private void InitializeArrangeState(ArrangeState arrangeState)
{
DataGrid parentDataGrid = ParentDataGrid;
double horizontalOffset = parentDataGrid.HorizontalScrollOffset;
double cellsPanelOffset = parentDataGrid.CellsPanelHorizontalOffset;
arrangeState.NextFrozenCellStart = horizontalOffset;
arrangeState.NextNonFrozenCellStart -= cellsPanelOffset;
arrangeState.ViewportStartX = horizontalOffset - cellsPanelOffset;
arrangeState.FrozenColumnCount = parentDataGrid.FrozenColumnCount;
}
た状態を初期化した後、それは、すべての実現チャイルズため
ArrangeChild(children[childIndex] as UIElement, i, arrangeState);
を呼び出し、非実現チャイルズ/列の推定幅を算出します。
double childSize = GetColumnEstimatedMeasureWidth(column, averageColumnWidth);
arrangeState.NextNonFrozenCellStart += childSize;
端における値はDataGrid
の適切なフィールドに設定されます。
private void FinishArrange(ArrangeState arrangeState)
{
DataGrid parentDataGrid = ParentDataGrid;
// Update the NonFrozenColumnsViewportHorizontalOffset property of datagrid
if (parentDataGrid != null)
{
parentDataGrid.NonFrozenColumnsViewportHorizontalOffset = arrangeState.DataGridHorizontalScrollStartX;
}
// Remove the clip on previous clipped child
if (arrangeState.OldClippedChild != null)
{
arrangeState.OldClippedChild.CoerceValue(ClipProperty);
}
// Add the clip on new child to be clipped for the sake of frozen columns.
_clippedChildForFrozenBehaviour = arrangeState.NewClippedChild;
if (_clippedChildForFrozenBehaviour != null)
{
_clippedChildForFrozenBehaviour.CoerceValue(ClipProperty);
}
}
あなたはsource codeにライン1470から見つけることができますArrangeChild(UIElement child, int displayIndex, ArrangeState arrangeState)
の詳細。それは作るの列が凍結されているように単純ではありません
結論
。これは、(離れて全幅にわたってクリッピングやスクロールバーから)
<ListView ItemsSource="some rows">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Fixed"
Background="LightBlue" Width="300"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" />
<TextBlock Grid.Column="1" Text="Scrolled"
Background="LightGreen" Width="300" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
に動作しますにもかかわらず、これはしません。
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Fixed"
Background="LightBlue" Width="300"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" />
<TextBlock Grid.Column="1" Text="Scrolled"
Background="LightGreen" Width="300" />
</Grid>
</ScrollViewer>
理由はSelectiveScrollingOrientation attached property
でDataGridHelper.FindVisualParent<ScrollViewer>(element)
は(souce codeにライン149から参照)が失敗したということです。あなたは回避策を見つけるかもしれません。元のコードのコピーを使用して独自の添付プロパティを作成しますが、名前はScrollViewer
になります。それ以外の場合は、最初から多くのことをしなければならないと思います。
凍結とはどういう意味ですか?サイズ? – Joe
DataGridやExcelなどのフリーズされた行/列。ヘッダーは常に表示されます。具体的には、上部の列見出しは水平方向にスクロールできますが、垂直方向にはスクロールできません。左側の行ヘッダーは垂直方向にスクロールできますが、水平方向にはスクロールできません。 – newman