मेरे द्वारा यह समस्या होने के बाद मैं अब तक जो कुछ पाया है उसे साझा करना चाहता हूं।
DataGrid
इसके लिए दो अलग-अलग तरीकों का उपयोग करता है।
पहले: RowHeader
इस सरलीकृत 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
जुड़ी संपत्ति का उपयोग करता है में RowHeader धारण करने के लिए पद। यदि यह प्रॉपर्टी सेट (या बदलती है) तो यह तत्व के लिए ऑफसेट के लिए माता-पिता ScrollViewer
ऑफसेट से अनुकूलित TranslateTransform
अनुकूलित है। 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);
}
}
ArrangeChild(UIElement child, int displayIndex, ArrangeState arrangeState)
के लिए विवरण आप source code में लाइन 1470 से पा सकते हैं।
निष्कर्ष
यह रूप में सरल बनाने कॉलम नहीं जमे हुए हैं है। हालांकि इस काम करेंगे (अलग कतरन और पूरी चौड़ाई से अधिक स्क्रॉलबार से)
<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>
कारण है कि DataGridHelper.FindVisualParent<ScrollViewer>(element)
SelectiveScrollingOrientation attached property
विफल रहता है में (souce code में लाइन 149 से देखें)। शायद आपको कामकाज मिलते हैं उदा। मूल कोड की एक प्रति के साथ अपनी स्वयं की संलग्न संपत्ति बनाएं लेकिन नाम से ScrollViewer
प्राप्त करें। अन्यथा मुझे लगता है कि आपको स्क्रैच से कई चीजें करना है।
जमे हुए से आपका क्या मतलब है? आकार? – Joe
डेटाग्रिड या एक्सेल में जमे हुए पंक्तियों/कॉलम, ताकि हेडर हमेशा दिखाई दे सकें। अधिक विशेष रूप से, शीर्ष पर कॉलम हेडर क्षैतिज स्क्रॉल कर सकते हैं, लेकिन लंबवत नहीं; बाईं ओर पंक्ति शीर्षलेख लंबवत स्क्रॉल कर सकते हैं, लेकिन क्षैतिज नहीं। – newman