代码之家  ›  专栏  ›  技术社区  ›  jrista

WPF样式层次结构?

  •  4
  • jrista  · 技术社区  · 15 年前

    我可能遗漏了WPF中的一些明显内容,但是是否可以创建与目标控件的子控件分层工作的样式?为了更好地解释这个问题,请考虑一下CSS是如何设计HTML样式的。您可以通过选择器以分层方式将CSS作为控件的目标:

    div > span em
    {
       color: blue;
    }
    
    ul.class > li ul li
    {
        display: block;
        margin: 0px;
    }
    

    有没有可能实现与WPF风格相同的东西?到目前为止,我一直在为每种类型的控件创建样式,或者直接应用于控件的命名样式。然而,我最终得到的样式比我真正想要的要多得多,而且我几乎不可能将控制结构作为一个组一起设计样式。

    谢谢你的洞察力。

    更新:

    下面是一个我想做的事情的例子。请注意,只有根ListView控件应用了样式。我希望能够以任何一个CellTemplate中的任何一个子控件为目标,而不必直接将样式应用于这些子控件中的每一个。这使我的视图布局标记与样式标记分离,从而使我可以更自由地更改样式,而无需为整个应用程序中的每个控件显式创建样式。

    <Grid>
      <ListView Style="{StaticResource ProcessableItemsListView}">
        <ListView.View>
          <GridView>
            <GridViewColumn Width="10">
              <GridViewColumn.CellTemplate>
                <Grid>
                  <CheckBox Value="{Binging ...}" />
                </Grid>
              </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Width="*">
              <GridViewColumn.CellTemplate>
                <Grid>
                  <TextBlock Text="{Binding ...}" />
                </Grid>
              </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Width="80">
              <GridViewColumn.CellTemplate>
                <Grid>
                  <Button Command="{Binding ...}">Process</Button>
                </Grid>
              </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Width="120">
              <GridViewColumn.CellTemplate>
                <Grid>
                  <ProgressBar Value="{Binding ...}" />
                </Grid>
              </GridViewColumn.CellTemplate>
            </GridViewColumn>
          </GridView>
        </ListView.View>
      </ListBiew>
    </Grid>
    
    3 回复  |  直到 15 年前
        1
  •  1
  •   Brad Cunningham    15 年前

    我本可以发表评论的,但文字已经用完了

    嗯,考虑到使用隐式风格的andyp的答案并不能解决你的问题,我可以想出两种稍微不同的方法来解决这个问题。

    一种是使网格单元格中的所有控件都成为简单的内容控件,并将数据对象绑定到控件的内容属性。然后,您可以创建针对数据对象的隐式样式,而不是UI控件类型。这与andyp建议的基本相同,但只是从数据的角度来看(在您的场景中可能不起作用)。

    我能想到的另一个解决方案是创建一个针对所有网格单元控件继承自的某个根uielement的样式。在样式中,添加一个触发器,根据某个值(名称、标记、其他数据绑定)交换控件的某些属性。

    不确定哪一个能得到你想要的,但值得一试。

    另外,你能发布一个代码片段来更清楚地显示你想要完成的工作吗?也许有一个更简单的方法来解决这个问题,我只是错过了。

        2
  •  0
  •   andyp    15 年前

    我不能百分之百地确定我是否正确理解您,但我认为您想要的是设计一个基类的样式,并将该样式应用于它的后代。

    因此,例如,如果要设置组合框的样式,可以编写:

    <Style x:Key="ComboBoxStyle" TargetType="ComboBox">
        ...
    </Style>
    

    但是你也可以写:

    <Style x:Key="ComboBoxStyle" TargetType="Control">
        ...
    </Style>
    

    并将该样式应用于控件的所有子代,而不仅仅是组合框。示例(直接和未编辑)取自 this 博客帖子。

        3
  •  0
  •   Brad Cunningham    15 年前

    您可以通过使用basedon属性来实现类似于CSS的样式继承

    <Style x:Key="A">
        <Setter Property="Background" Value="Blue" />
    </Style> 
    
    <Style x:Key="B" BasedOn="{StaticResource A}">
        <Setter Property="Foreground" Value="Red" />
    </Style> 
    
    <Style x:Key="C" BasedOn="{StaticResource A">
        <Setter Property="Foreground" Value="White" />
    </Style> 
    

    这有帮助吗?