Windows Phone 7-为选定的ListBoxItem中的特定控件设置样式 [英] Windows Phone 7 - Setting style for specific control within selected ListBoxItem

查看:81
本文介绍了Windows Phone 7-为选定的ListBoxItem中的特定控件设置样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这样的东西:

<Grid>
    <ListBox x:Name="list" 
        ItemsSource="{Binding SomeCollection, Mode=TwoWay}" 
        SelectedItem="{Binding SomeItem, Mode=TwoWay}">                    
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock x:Name="first" Text="{Binding SomeProperty}" />
                <TextBlock x:Name="second" Text="{Binding OtherProperty}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

现在,如何更改仅的某些样式属性(例如FontSize) 当选择ListBoxItem时,称为第二个的TextBlock?如果我想为所有ListBoxItem的内容设置FontSize,那么我将没有问题。

Now, how do i alter some style property (f.ex. FontSize) of only the TextBlock called "second" when a ListBoxItem gets selected? If i'd like to set the FontSize for all ListBoxItem's contents, then i'd have no problem. That scenario is quite well documented here and elsewhere on the web.

推荐答案

我不会给您确切的解决方案,但是很好开头为:签出文件

I will not give you an exact solution, but a good point to start with: check out the file

C:\Program Files\Microsoft SDKs\Windows Phone\vX.Y\Design\System.Windows.xaml

您必须将XY调整为7.0 / 7.1以及您的设置。在那里,您会发现与WP7 / Silverlight的所有基本UI控件都在使用的控件模板完全相同。在VisualStudio或其他版本中打开它,然后搜索:

you have to adjust X.Y to 7.0/7.1 along with your setup. There you will find exactly the same Control-Templates that are being used all the basic UI Controls of the WP7/Silverlight. Open it in VisualStudio-or-whateverelse and search for:

<Style TargetType="ListBoxItem">
  (... and immediatelly following ~40 lines of xaml)

我已经打开该文件,这里就是

ah well, since I've opened that file, here's that

    <!--x:Key="PhoneListBoxItem"-->
    <Style TargetType="ListBoxItem">
      <Setter Property="Background" Value="Transparent"/>
      <Setter Property="BorderThickness" Value="0" />
      <Setter Property="BorderBrush" Value="Transparent" />
      <Setter Property="Padding" Value="0" />
      <Setter Property="HorizontalContentAlignment" Value="Left"/>
      <Setter Property="VerticalContentAlignment" Value="Top"/>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem">
            <Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
              <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                  <VisualState x:Name="Normal"/>
                  <VisualState x:Name="MouseOver" />
                  <VisualState x:Name="Disabled">
                    <Storyboard>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Background">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                      <DoubleAnimation Storyboard.TargetName="ContentContainer" Storyboard.TargetProperty="Opacity" Duration="0" To=".5" />
                    </Storyboard>
                  </VisualState>
                </VisualStateGroup>
                <VisualStateGroup x:Name="SelectionStates">
                  <VisualState x:Name="Unselected"/>
                  <VisualState x:Name="Selected">
                    <Storyboard>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer" Storyboard.TargetProperty="Foreground">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                  </VisualState>
                </VisualStateGroup>
              </VisualStateManager.VisualStateGroups>
              <ContentControl x:Name="ContentContainer" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
                Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" Foreground="{TemplateBinding Foreground}" />
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

这是 DEFAULT ListBoxItem的完整样式-您想要的东西改变。略过代码并注意'ContentPresenter'和'VisualStateGroup x:Name = SelectionStates'之前。

This is the complete style for your DEFAULT ListBoxItem - the thing you want to alter. Skim through the code and note the 'ContentPresenter' and preceding 'VisualStateGroup x:Name="SelectionStates"'.

ContentPresenter是显示项目的DataTemplate的东西该组中的
VisualStates定义了从正常状态发生的更改,如果在列表元素上触发了选定状态,则应该发生这些变化。

选择状态减小后,元素将自动返回到未选择状态,并且其视觉效果随之而来。还要注意,未选择的视觉状态不会强制执行任何更改-因此会保留您原始的DataTemplate样式。

ContentPresenter is the thing that will show your DataTemplate for the item.
VisualStates in that group define the changes from the normal state that should occur if a "selected state" is fired of on an list element.
Once the "selection state" diminishes, the element returns to the unselected state automatically and his visuals follow. Note also that the Unselected visual state does not enforce any changes - so it preserves your plain DataTemplate style.

最后要注意的是,这是ListBoxItem的样式,和 not 分别代表您的数据项和数据模板。您的DataTemplate永不被触摸,它由ContentPresenter直接显示。 ListBox将所有项目包装在 ListBoxItem实例中,然后显示这些ListBoxItem并将其应用于这些样式。

The last thing to notice is that this is a style for ListBoxItem, and not for your data-item, nor your data-template. Your DataTemplate is never touched, it is directly displayed by the ContentPresenter. The ListBox wraps all your items in "ListBoxItem" instances, then displays those ListBoxItems and applies that style to them.

恕我直言,这是您必须使用的要点。

IMHO, this is the point you will have to work with.

您可能希望根据需要复制并更改此样式,然后将 ListBox.ItemContainerStyle 设置为该 new 样式。一种方法是:

You may want to copy&alter this style to your needs, and then set your ListBox.ItemContainerStyle to that new style. One of the ways is:

<YourPage.Resources>
    <Style x:Key="mylistboxitemoverride" .....
        ........
    </Style>
</YourPage.Resources>
...
...
<ListBox ......... ItemContainerStyle="{StaticResource mylistboxitemoverride}"
    ...
    ...
</ListBox>

现在,诀窍是修改选定的 VisualState,并使其不更改前景(这样做会重新设置两个TextBox的样式!),但会影响其他一些仅影响您的txb的属性。不幸的是,这可能更难/更丑。我那时还不知道如何使它更漂亮,而不是用DataTemplate硬替换ContentPresenter并像这样在VisualState中引用您的确切叶文本框:

Now, the trick is to modify the 'Selected' VisualState, and make it alter not the Foreground (doing that would restyle both your TextBoxes!), but some other property which will affect only one of your txbs. Unfortunatelly, that may be harder/uglier. I don't at that moment any idea how to make it "prettier" than hard-replacing the ContentPresenter with your DataTemplate and referencing your exact leaf-textbox in the VisualState like that:

    <Style .... TargetType="ListBoxItem">
      <Setter Property="Background" Value="Transparent"/>
      <Setter Property="BorderThickness" Value="0" />
      <Setter Property="BorderBrush" Value="Transparent" />
      <Setter Property="Padding" Value="0" />
      <Setter Property="HorizontalContentAlignment" Value="Left"/>
      <Setter Property="VerticalContentAlignment" Value="Top"/>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem">
            <Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
              <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                  <VisualState x:Name="Normal"/>
                  <VisualState x:Name="MouseOver" />
                  <VisualState x:Name="Disabled">
                    <Storyboard>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Background">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TransparentBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                      <DoubleAnimation Storyboard.TargetName="SECOND" Storyboard.TargetProperty="Opacity" Duration="0" To=".5" /> <!-- #### RETARGETTED -->
                    </Storyboard>
                  </VisualState>
                </VisualStateGroup>
                <VisualStateGroup x:Name="SelectionStates">
                  <VisualState x:Name="Unselected"/>
                  <VisualState x:Name="Selected">
                    <Storyboard>
                      <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SECOND" Storyboard.TargetProperty="Foreground"> <!-- #### RETARGETTED -->
                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                      </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                  </VisualState>
                </VisualStateGroup>
              </VisualStateManager.VisualStateGroups>

              <!-- #### INLINED YOUR DATATEMPLATE -->
              <StackPanel Orientation="Vertical"
                          Margin="{TemplateBinding Padding}"
                          DataContext="{TemplateBinding Content}">  <!-- #### careful with the bindings. the DataCtx may be needed or is spurious. do check that! -->
                <TextBlock Text="{Binding SomeProperty}" />  <!-- #### referenced from nowhere, so I removed the name -->
                <TextBlock x:Name="SECOND" Text="{Binding OtherProperty}" />
              </StackPanel>

            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

这应该几乎是您想要的,或者至少非常接近它。我尚未对其进行测试,您可能需要修改适当的数据绑定(我提供了DataContent = binding:Content,但这是一个快速的猜测),可能您想添加自己的动画。我认为您现在可以进行大量尝试。玩得开心!

This should be almost what you want, or at least very close to it. I have not tested it, you may need to tinker with proper data-binding (I've included a DataContent=binding:Content, but that's a quick guess) and probably you will want to add your own animations. I think you have now tons of bits to experiment with. Have fun!

这篇关于Windows Phone 7-为选定的ListBoxItem中的特定控件设置样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆