在嵌套的 TabControl 中滚动
Scrolling in nested TabControl
我有一个使用选项卡控件的 wpf 应用程序。结构如下所示:
/*MainView*/
<UserControl>
<UserControl.Resources>
<DataTemplate DataType="{x:Type tapViewModels:TabViewModel}">
<tabViews:TabView />
</DataTemplate>
</UserControl.Resources>
<ScrollViewer Name="MainScrollViewer" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
...
</Grid>
<Grid Grid.Row="1">
<dx:DXTabControl ItemsSource="{Binding TabItems}" SelectedIndex="0">
<dx:DXTabControl.ItemHeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Header}" />
</DataTemplate>
</dx:DXTabControl.ItemHeaderTemplate>
<dx:DXTabControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Path=Content}" /> /*Content = new TabViewModel()*/
</DataTemplate>
</dx:DXTabControl.ItemTemplate>
</dx:DXTabControl>
</Grid>
</Grid>
</ScrollViewer>
</UserControl>
/*TabView*/
<UserControl>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
...
</Grid>
<Grid Grid.Row="1">
<dxg:GridControl>
<dxg:TableView>
...
</dxg:TableView>
</dxg:GridControl>
</Grid>
</Grid>
</UserControl>
当我在悬停 GridControl 的同时向上滚动时,如果 GridControl 已经滚动到顶部,我希望滚动事件 "bubble" 向上。当然,当在底部蜂鸣时向下滚动时也是如此。
我的问题是,GridControl 和 ScrollViewer 存在于两个不同的视图中,并且具有两个不同的 ViewModel。那么我怎样才能使它起作用呢?
我会喜欢。一个 MVVM 解决方案,但此时我对任何事情都持开放态度!
可以处理下层控件的MouseWheel事件,判断是否滚动到顶部,再引发上层控件的事件:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<wpfApplication3:ControlA x:Name="A" Grid.Row="0" />
<wpfApplication3:ControlB x:Name="B" Grid.Row="1" PreviewMouseWheel="HandleMouseWheel"/>
</Grid>
然后在 HandleMouseWheel 事件中:
private void HandleMouseWheel(object sender, MouseWheelEventArgs e)
{
var controlB = sender as ControlB;
if (controlB != null && e.Delta > 0 && controlB.Scroll.VerticalOffset == 0)
{
e.Handled = true;
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
{
RoutedEvent = UIElement.MouseWheelEvent,
Source = sender
};
A.Scroll.RaiseEvent(eventArg);
}
}
e.Delta 检查您是否向上滚动鼠标,VerticalOffset 检查确保控件已经滚动到顶部。
这假设您的用户控件中有一个公开可用的滚动查看器,例如:
<UserControl>
<ScrollViewer x:Name="Scroll">
<Grid Height="1000"></Grid>
</ScrollViewer>
</UserControl>
我有一个使用选项卡控件的 wpf 应用程序。结构如下所示:
/*MainView*/
<UserControl>
<UserControl.Resources>
<DataTemplate DataType="{x:Type tapViewModels:TabViewModel}">
<tabViews:TabView />
</DataTemplate>
</UserControl.Resources>
<ScrollViewer Name="MainScrollViewer" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
...
</Grid>
<Grid Grid.Row="1">
<dx:DXTabControl ItemsSource="{Binding TabItems}" SelectedIndex="0">
<dx:DXTabControl.ItemHeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Header}" />
</DataTemplate>
</dx:DXTabControl.ItemHeaderTemplate>
<dx:DXTabControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding Path=Content}" /> /*Content = new TabViewModel()*/
</DataTemplate>
</dx:DXTabControl.ItemTemplate>
</dx:DXTabControl>
</Grid>
</Grid>
</ScrollViewer>
</UserControl>
/*TabView*/
<UserControl>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
...
</Grid>
<Grid Grid.Row="1">
<dxg:GridControl>
<dxg:TableView>
...
</dxg:TableView>
</dxg:GridControl>
</Grid>
</Grid>
</UserControl>
当我在悬停 GridControl 的同时向上滚动时,如果 GridControl 已经滚动到顶部,我希望滚动事件 "bubble" 向上。当然,当在底部蜂鸣时向下滚动时也是如此。
我的问题是,GridControl 和 ScrollViewer 存在于两个不同的视图中,并且具有两个不同的 ViewModel。那么我怎样才能使它起作用呢?
我会喜欢。一个 MVVM 解决方案,但此时我对任何事情都持开放态度!
可以处理下层控件的MouseWheel事件,判断是否滚动到顶部,再引发上层控件的事件:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<wpfApplication3:ControlA x:Name="A" Grid.Row="0" />
<wpfApplication3:ControlB x:Name="B" Grid.Row="1" PreviewMouseWheel="HandleMouseWheel"/>
</Grid>
然后在 HandleMouseWheel 事件中:
private void HandleMouseWheel(object sender, MouseWheelEventArgs e)
{
var controlB = sender as ControlB;
if (controlB != null && e.Delta > 0 && controlB.Scroll.VerticalOffset == 0)
{
e.Handled = true;
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
{
RoutedEvent = UIElement.MouseWheelEvent,
Source = sender
};
A.Scroll.RaiseEvent(eventArg);
}
}
e.Delta 检查您是否向上滚动鼠标,VerticalOffset 检查确保控件已经滚动到顶部。
这假设您的用户控件中有一个公开可用的滚动查看器,例如:
<UserControl>
<ScrollViewer x:Name="Scroll">
<Grid Height="1000"></Grid>
</ScrollViewer>
</UserControl>