我正在尝试实现一种方法,将数据网格的滚动条移回到此示例http://www.codeproject.com/Articles/109531/Controlling-and-Viewing-the-ScrollBar-Positions-of之后的前一个位置,但此方法始终返回null,因此无法创建自动化。有没有人知道为什么这总是会返回null?
public static IScrollProvider GetScrollProvider(DataGrid grid)
{
var p = FrameworkElementAutomationPeer.FromElement(grid)
?? FrameworkElementAutomationPeer.CreatePeerForElement(grid);
return p.GetPattern(PatternInterface.Scroll) as IScrollProvider;
}
答案 0 :(得分:1)
古代历史,但至少目前的版本似乎在所有情况下都像魅力一样。
//p.GetPattern(PatternInterface.Scroll) as IScrollProvider;
{System.Windows.Automation.Peers.DataGridAutomationPeer}
[System.Windows.Automation.Peers.DataGridAutomationPeer]:
{System.Windows.Automation.Peers.DataGridAutomationPeer}
HorizontallyScrollable: true
HorizontalScrollPercent: 0.0
HorizontalViewSize: 81.44329896907216
VerticallyScrollable: true
VerticalScrollPercent: 29.062733871459486
VerticalViewSize: 2.9625
答案 1 :(得分:0)
我知道它是一个旧帖子,但万一有人带着同样的问题来到这里,(像我一样),这就是我解决它的方法:
出于某种原因,当您使用DataGrid的滚动条时,如果用户还没有滚动,它将通知最大位置为0,即使它不是。所以我在更新之前保存了最大值,并在之后恢复它:
首先我创建一个类来保存这些值。它可能是变量,但是一个类似乎更有条理:
public static ScrollInfo GetScrollInfo(this DataGrid grid)
{
ScrollInfo oInfo = new ScrollInfo();
ScrollBar sbHorizontal = grid.GetScrollbar(ScrollMode.Horizontal);
oInfo.HorizontalMaximum = sbHorizontal.Maximum;
oInfo.HorizontalPosition = sbHorizontal.Value;
ScrollBar sbVertical = grid.GetScrollbar(ScrollMode.Vertical);
oInfo.VerticalMaximum = sbVertical.Maximum;
oInfo.VerticalPosition = sbVertical.Value;
return oInfo;
}
在更新ItemSource属性之前,我使用此方法保存滚动信息:
public static void SetScrollPosition(this DataGrid grid, ScrollInfo info)
{
if (info.HorizontalPosition > 0)
{
ScrollBar sbHorizontal = grid.GetScrollbar(ScrollMode.Horizontal);
sbHorizontal.Maximum = info.HorizontalMaximum;
grid.Scroll(ScrollMode.Horizontal, info.HorizontalPosition);
}
if (info.VerticalPosition > 0)
{
ScrollBar sbVertical = grid.GetScrollbar(ScrollMode.Vertical);
sbVertical.Maximum = info.VerticalMaximum;
grid.Scroll(ScrollMode.Vertical, info.VerticalPosition);
}
}
然后我调用此方法在更新后将此信息设置回网格:
public static void UpdateItemSource(this DataGrid grid, IEnumerable itemSource)
{
ScrollInfo oInfo = grid.GetScrollInfo();
grid.ItemsSource = itemSource;
grid.SetScrollPosition(oInfo);
}
我甚至创建了一个UpdateItemSource方法来简化操作:
public static void Scroll(this DataGrid grid, ScrollMode mode, double position)
{
// Get the scrollbar and convert the position to percent.
var scrollBar = grid.GetScrollbar(mode);
double positionPct = ((position / scrollBar.Maximum) * 100);
// Scroll to a specfic percentage of the scrollbar.
grid.ScrollToPercent(mode, positionPct);
}
public static void ScrollToPercent(this DataGrid grid, ScrollMode mode, double percent)
{
// Fix the percentage.
if (percent < 0)
percent = 0;
else if (percent > 100)
percent = 100;
// Get the scroll provider.
var scrollProvider = GetScrollProvider(grid);
// Scroll.
switch (mode)
{
case ScrollMode.Vertical:
scrollProvider.SetScrollPercent( System.Windows.Automation.ScrollPatternIdentifiers.NoScroll, percent);
break;
case ScrollMode.Horizontal:
scrollProvider.SetScrollPercent(percent, System.Windows.Automation.ScrollPatternIdentifiers.NoScroll);
break;
}
}
我使用的其他方法,我想我会从发布问题的用户的同一帖子中提到:
class FooBehavior : Behavior<Foo>
{
public static readonly DependencyProperty FooPropProperty = DependencyProperty.Register("FooProp", typeof(string), typeof(FooBehavior),
new FrameworkPropertyMetadata(FooPropProperty_Changed)
{
BindsTwoWayByDefault = true,
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
});
public String FooProp { get { return (string)GetValue(FooPropProperty); } set { SetValue(FooPropProperty, value); } }
private static void FooPropProperty_Changed(object sender, DependencyPropertyChangedEventArgs args)
{
/* re-entrancy check done here*/
// ...
if (/* args.NewValue is something bad that I can't use */)
FooProp = (string)args.OldValue;
try
{
/* do stuff here that might throw */
}
catch
{
FooProp = /* some known good value */;
throw;
}
}
}