我在滚动浏览器中水平显示图像列表,我正在使用以下代码行进行此操作
<ScrollViewer Name="lviewThumbnails" Height="230" >
<ItemsControl ItemsSource="{Binding ThumbsCollection}" MouseWheel="ItemsControl_MouseWheel" >
<ItemsControl.ItemTemplate >
<DataTemplate>
<DockPanel Height="230">
<Button Name="pageThumbnail" DockPanel.Dock="Top" Tag="{Binding}" VerticalAlignment="Top" Margin="5,2">
<Grid>
<Image MaxWidth="140" Height="200" Source="{Binding ThubnailPath,IsAsync=True}" Stretch="None"></Image>
</Grid>
</Button>
<Label HorizontalAlignment="Center" FontSize="14" FontWeight="Bold" Content="text" Foreground="White" Padding="5"></Label>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
当我打开视图时,我想将焦点设置为此列表中的特定图像项 例如,如果列表中有150个图像,并且我想在打开列表时将焦点设置为图像
我正在做的是按下按钮我正在设置此代码
lviewThumbnails.Visibility = Visibility.Visible;
使图像可见,但每次都是默认选择的第一项。 我正在使用触发器来检测所选图像,就像这样
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter TargetName="pageThumbnail" Property="BorderBrush" Value="Yellow"/>
<Setter TargetName="pageThumbnail" Property="BorderThickness" Value="3"/>
</DataTrigger>
但问题是如果图像75是选中的,我可以在图像75周围看到黄色边框,但是当我点击按钮时焦点仍然在图像1上。我必须前一个,滚动查看器的下一个按钮才能到达图片75。 我正在使用我的滚动查看器,具有特定样式,如第1列,按钮第2列内容,第3列再次按钮(希望它不影响默认行为),我阻止滚动查看器上的鼠标滚动
<ControlTemplate TargetType="{x:Type ScrollViewer}" x:Key="ButtonOnlyScrollViewer">
<ControlTemplate.Resources>
</ControlTemplate.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource ResourceKey=ViewPreviousButton}" Grid.Column="0" Command="ScrollBar.PageUpCommand" MouseWheel="ItemsControl_MouseWheel"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Button>
<ScrollContentPresenter
CanContentScroll="{TemplateBinding CanContentScroll}"
Grid.Column="1"
Content="{TemplateBinding Content}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Margin="{TemplateBinding Margin}"/>
<Button Style="{StaticResource ResourceKey=ViewNextButton}" Grid.Column="2" Command="ScrollBar.PageDownCommand" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MouseWheel="ItemsControl_MouseWheel"
></Button>
</Grid>
</ControlTemplate>
答案 0 :(得分:0)
您可以使用触发器执行此操作,并为所选项目或任何适合您的方式设置单独的模板。
这样的事情,假设您将图像ID作为属性;
<DataTrigger Binding="{Binding ThumbsCollection.ImageId}" Value="75">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
</DataTrigger>
答案 1 :(得分:0)
在这种情况下,您可以使用附加属性FocusManager.FocusedElement
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter TargetName="pageThumbnail" Property="BorderBrush" Value="Yellow"/>
<Setter TargetName="pageThumbnail" Property="BorderThickness" Value="3"/>
<Setter TargetName="pageThumbnail" Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"/>
</DataTrigger>
或
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter TargetName="pageThumbnail" Property="BorderBrush" Value="Yellow"/>
<Setter TargetName="pageThumbnail" Property="BorderThickness" Value="3"/>
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=pageThumbnail}"/>
</DataTrigger>
如果上面没有正确聚焦,那么先尝试聚焦容器然后聚焦pageThumbnail
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter TargetName="pageThumbnail" Property="BorderBrush" Value="Yellow"/>
<Setter TargetName="pageThumbnail" Property="BorderThickness" Value="3"/>
<Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"/>
<Setter TargetName="pageThumbnail" Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"/>
</DataTrigger>
<强>更新强>
问题不仅仅是焦点,而是元素的位置,因为它不在视图的一边
试试这个xaml
<ItemsControl ItemsSource="{Binding ThumbsCollection}" MouseWheel="ItemsControl_MouseWheel" Name="singleThumbs">
<ItemsControl.Resources>
<Style TargetType="ContentPresenter" xmlns:l="clr-namespace:WPFPerfomanceTest">
<Setter Property="l:ScrollProvider.ScrollIntoView"
Value="{Binding IsSelected}" />
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate >
<DataTemplate>
<DockPanel Height="230">
<Button Name="pageThumbnail" DockPanel.Dock="Top" Tag="{Binding}" VerticalAlignment="Top" Margin="5,2" Width="140">
<Grid>
<Image Height="200" Source="{Binding ThubnailPath,IsAsync=True}" Stretch="None"></Image>
</Grid>
</Button>
<Label HorizontalAlignment="Center" FontSize="14" FontWeight="Bold" Content="{Binding PageNo}" Foreground="White" Padding="5"></Label>
</DockPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True" >
<Setter TargetName="pageThumbnail" Property="BorderBrush" Value="Yellow"/>
<Setter TargetName="pageThumbnail" Property="BorderThickness" Value="3"/>
<Setter TargetName="pageThumbnail" Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
请注意,我为ContentPresenter添加了样式并将ScrollProvider.ScrollIntoView绑定到IsSelected属性
还从图像中删除了最大宽度,并为按钮指定了Width =“140”。最大宽度导致按钮大小缩小,直到图像被加载,这有效地阻止了带来查看行为
并使其正常工作
我们需要一些附加行为,将此类添加到您的项目
class ScrollProvider : DependencyObject
{
public static bool GetScrollIntoView(DependencyObject obj)
{
return (bool)obj.GetValue(ScrollIntoViewProperty);
}
public static void SetScrollIntoView(DependencyObject obj, bool value)
{
obj.SetValue(ScrollIntoViewProperty, value);
}
// Using a DependencyProperty as the backing store for ScrollIntoView. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ScrollIntoViewProperty =
DependencyProperty.RegisterAttached("ScrollIntoView", typeof(bool), typeof(ScrollProvider), new PropertyMetadata(false, OnScrollIntoViewChanged));
private static void OnScrollIntoViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = d as FrameworkElement;
if ((bool)e.NewValue)
{
element.BringIntoView();
element.Focus();
}
}
}
答案 2 :(得分:0)
如果你想设置焦点或显示一些效果,你可以绑定IsFocus并使用触发器
private void Button_Click(object sender, RoutedEventArgs e)
{
lviewThumbnails.Visibility = Visibility.Visible;
int index = 75;
ThumbsCollection[index].IsFocus = true;
Button button = (Button)FindFirstVisualChild(lviewThumbnails, "pageThumbnail");
lviewThumbnails.ScrollToHorizontalOffset((button.ActualWidth + 6.5) * index); // set it with pageThumbnail's location or margin
}
public object FindFirstVisualChild(DependencyObject obj, string childName)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child.GetValue(NameProperty).ToString() == childName)
{
return child;
}
else
{
object childOfChild = FindFirstVisualChild(child, childName);
if (childOfChild != null)
{
return childOfChild;
}
}
}
return null;
}
我想你想在屏幕上显示第75个(中间项目)项目,因此你可以使用ScrollToHorizontalOffset
。首先获取按钮的实际值并在计算中获取它的边距/填充,然后您将获得偏移量。
答案 3 :(得分:0)
所有这些答案都遗漏了关于ItemsControls的令人讨厌的一些 key 信息。他们使用虚拟化,因此只有视图中实际存在的项目(以及一些周围的项目)实际上“存在”。 OP使用上面给出的答案是不可能的,因为第75个图像实际上还不存在,所以你不能将焦点设置到它。
你需要:
1)订阅ItemsControl ItemContainerGenerator.StatusChanged事件 2)设置滚动位置,使第75项滚动到视图中 3)在StatusChanged事件处理程序中,等待第75项的status = ContainerGenerated,然后取消订阅并设置焦点
是的,这太复杂了,是的,代码将“立即”执行,但您必须等到为第75个项目生成容器后能够将焦点设置到它。这就是虚拟化的工作原理。
当您只创建了项目1 - 10时,您正尝试将焦点设置为第75项。