如何在 LongListSelector SelectedItem 周围创建边框 [英] How to Create Border around LongListSelector SelectedItem
问题描述
我想在 LongListSelector
中围绕当前选定的项目创建一个边框,但我无法正确实现.从引用 http://code.msdn.microsoft.com/wpapps/Highlight-a-selected-item-30ced444 我尝试按照示例代码创建自定义 Style
来管理所选项目的更改,尽管我试图在周围放置边框图像而不是文本框.另外,我有一个自定义 ItemTemplate
作为我的 DataTemplate
用于我的 LongListSelector
,它管理我绑定图像的大小并控制所需的 每个项目的 ContextMenu
.
I would like to create a border around the currently selected item within a LongListSelector
, but I am having trouble getting the proper implementation. From referencing http://code.msdn.microsoft.com/wpapps/Highlight-a-selected-item-30ced444 I have tried to follow the sample code by creating a custom Style
to manage the selected item change, although I am trying to place a border around an image instead of a textbox. Also, I do have a custom ItemTemplate
as my DataTemplate
for my LongListSelector
which manages the size of my bound images and controls a required ContextMenu
for each item.
出于某种原因,我无法调整示例以在所选项目周围放置边框,但到目前为止我所拥有的内容如下
For some reason, I am having trouble adapting the sample to place a border around a selected item, but what I have so far is as follows
MainPage.xaml
MainPage.xaml
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="ItemTemplate">
<!--<Border x:Name="brd" CornerRadius="10" BorderBrush="{StaticResource PhoneAccentBrush}" Width="Auto" BorderThickness="3">-->
<Border x:Name="brd" CornerRadius="10" Width="Auto" BorderThickness="3">
<Viewbox Width="108" Height="108">
<Image x:Name="recentImage" Source="{Binding Source}" Margin="6,6" Width="108"/>
</Viewbox>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="imgListContextMenu" Background="{StaticResource PhoneChromeBrush}">
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="edit" Click="editContextMenuItem_Click"/>
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="favorite" Click="favoriteContextMenuItem_Click"/>
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="delete" Click="deleteContextMenuItem_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Border>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
...
<phone:LongListSelector x:Name="Recent" Margin="0"
Style="{StaticResource MyLongListSelectorStyle}"
SelectionChanged="recent_SelectionChanged"
toolkit:TiltEffect.IsTiltEnabled="True"
LayoutMode="Grid" GridCellSize="108,108"
ItemTemplate="{StaticResource ItemTemplate}"
/>
应用程序.xaml
<Style x:Key="MyLongListSelectorStyle" TargetType="phone:LongListSelector" >
<!--<Setter Property="LayoutMode" Value="List"/>-->
<Setter Property="LayoutMode" Value="Grid"/>
<!--<Setter Property="FontFamily" Value="Times New Roman"/>-->
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<UserControl>
<Border x:Name="MyBorder" Background="Transparent">
<VisualStateManager.VisualStateGroups >
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="MyBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!--<StackPanel>
<TextBlock x:Name="textBlock" Text="{Binding}" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>-->
</Border>
</UserControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
MainPage.xaml.cs
MainPage.xaml.cs
private void recent_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var s = sender as LongListSelector;
var item = (sender as LongListSelector).SelectedItem;
if (item == null)
return;
// Get item of LongListSelector.
List<UserControl> listItems = new List<UserControl>();
GetItemsRecursive<UserControl>(Recent, ref listItems);
// Selected.
if (e.AddedItems.Count > 0 && e.AddedItems[0] != null)
{
foreach (UserControl userControl in listItems)
{
if (e.AddedItems[0].Equals(userControl.DataContext))
{
VisualStateManager.GoToState(userControl, "Selected", true);
}
}
}
// Unselected.
if (e.RemovedItems.Count > 0 && e.RemovedItems[0] != null)
{
foreach (UserControl userControl in listItems)
{
if (e.RemovedItems[0].Equals(userControl.DataContext))
{
VisualStateManager.GoToState(userControl, "Normal", true);
}
}
}
}
public static void GetItemsRecursive<T>(DependencyObject parents, ref List<T> objectList) where T : DependencyObject
{
var childrenCount = VisualTreeHelper.GetChildrenCount(parents);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parents, i);
if (child is T)
{
objectList.Add(child as T);
}
GetItemsRecursive<T>(child, ref objectList);
}
return;
}
我被困在这里该怎么做,有什么想法吗?
I'm stuck on what to do from here, any ideas?
EDIT** 稍微改变了实现,但仍然不起作用.
EDIT** slightly changed implementation but still not working.
MainPage.xaml
MainPage.xaml
<phone:PhoneApplicationPage.Resources>
<Style x:Key="MyLongListSelectorStyle" TargetType="phone:LongListSelector" >
<!--<Setter Property="LayoutMode" Value="List"/>-->
<Setter Property="LayoutMode" Value="Grid"/>
<!--<Setter Property="FontFamily" Value="Times New Roman"/>-->
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<UserControl>
<!--<Border x:Name="MyBorder" Background="Transparent">-->
<Border x:Name="MyBorder" Background="Transparent">
<VisualStateManager.VisualStateGroups >
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<Storyboard>
<!--<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="MyBorder">-->
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderThickness" Storyboard.TargetName="brd">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="brd" CornerRadius="10" Width="Auto" BorderThickness="3">
<!--<Border x:Name="brd" CornerRadius="10" Width="Auto" BorderThickness="3">-->
<Viewbox Width="108" Height="108">
<Image x:Name="recentImage" Source="{Binding Source}" Margin="6,6" Width="108"/>
</Viewbox>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="imgListContextMenu" Background="{StaticResource PhoneChromeBrush}">
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="edit" Click="editContextMenuItem_Click"/>
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="favorite" Click="favoriteContextMenuItem_Click"/>
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="delete" Click="deleteContextMenuItem_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Border>
<!--<StackPanel>
<TextBlock x:Name="textBlock" Text="{Binding}" TextWrapping="Wrap" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>-->
</Border>
</UserControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources>
...
<phone:LongListSelector x:Name="Recent" Margin="0"
Style="{StaticResource MyLongListSelectorStyle}"
SelectionChanged="recent_SelectionChanged"
toolkit:TiltEffect.IsTiltEnabled="True"
LayoutMode="Grid" GridCellSize="108,108"
/>
MainPage.xaml.cs
MainPage.xaml.cs
//remains the same
推荐答案
我现在无法测试,因为我在工作,我只有 VS2010 但尝试更改
I can't test it rigth now because I'm at work and I only have VS2010 but try changing
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
您需要使用整数.您正在尝试使用颜色更改边框的粗细.
You need to use an integer. You are trying to change the thickness of the border using a color.
<DiscreteObjectKeyFrame KeyTime="0" Value="3"/>
似乎 LongListSelector 不让我们轻松地模板化所选项目...随着Johannes Wanzek的解决方案https://stackoverflow.com/a/13874389/1408558我设法做你想做的事:
It seems that LongListSelector don't let us easily template the selected item... With the solution of Johannes Wanzek https://stackoverflow.com/a/13874389/1408558 I managed to do what you want:
删除旧的 xaml 和代码背后的代码,然后按照以下步骤操作.
Delete your old xaml and code behind code, and follow these steps.
您需要将这些样式放在页面顶部
You need to put those styles on top of your page
<phone:PhoneApplicationPage.Resources>
<Style x:Key="PhoneButtonBase" TargetType="ButtonBase">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
<Setter Property="Padding" Value="10,5,10,6"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ButtonBase">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneButtonBasePressedForegroundBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
<DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0" Margin="{StaticResource PhoneTouchTargetOverhang}">
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="PhoneRadioButtonCheckBoxBase" BasedOn="{StaticResource PhoneButtonBase}" TargetType="ToggleButton">
<Setter Property="Background" Value="{StaticResource PhoneRadioCheckBoxBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneRadioCheckBoxBorderBrush}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMedium}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="0"/>
</Style>
<Style x:Key="RadioButtonStyle1" BasedOn="{StaticResource PhoneRadioButtonCheckBoxBase}" TargetType="RadioButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked"/>
<VisualState x:Name="Unchecked"/>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources>
然后像这样使用 LongListSelector:
And then use the LongListSelector like this:
<phone:LongListSelector x:Name="Recent" Margin="0"
toolkit:TiltEffect.IsTiltEnabled="True"
LayoutMode="Grid" GridCellSize="108,108" >
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<ContentControl HorizontalAlignment="Stretch" HorizontalContentAlignment="Left">
<ContentControl.Resources>
<Storyboard x:Name="CheckedStoryboard">
<ColorAnimation Duration="0" To="Red" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="brd" d:IsOptimized="True"/>
</Storyboard>
</ContentControl.Resources>
<RadioButton x:Name="radioButton" HorizontalAlignment="Stretch" Margin="0,0,0,0" GroupName="A" Background="Black" Style="{StaticResource RadioButtonStyle1}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<eim:ControlStoryboardAction Storyboard="{StaticResource CheckedStoryboard}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<eim:ControlStoryboardAction ControlStoryboardOption="Stop" Storyboard="{StaticResource CheckedStoryboard}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Border x:Name="MyBorder" Background="Transparent">
<Border x:Name="brd" CornerRadius="10" Width="Auto" BorderThickness="3" BorderBrush="Transparent">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="imgListContextMenu" Background="{StaticResource PhoneChromeBrush}">
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="edit"/>
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="favorite"/>
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="delete"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<Viewbox Width="108" Height="108">
<Image x:Name="recentImage" Source="{Binding Source}" Margin="6,6" Width="108"/>
</Viewbox>
</Border>
</Border>
</RadioButton>
</ContentControl>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
这里有一些您可能需要的命名空间:
And here some of the namespaces you may need:
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:eim="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactions"
这篇关于如何在 LongListSelector SelectedItem 周围创建边框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!