我的Style适用于我的应用程序的所有按钮:
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="StatusButtonCircle" Stroke="Black" StrokeThickness="0" Fill="AliceBlue" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircle" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<Ellipse x:Name="StatusButtonCircleHighlight" Margin="4" Stroke="Black" StrokeThickness="2" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircleHighlight" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
... some Triggers here
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
如何在XAML中更改属性(例如FontWeight,FontSize等)?我试过这个:
<Button FontWeight="Bold" FontSize="30" Foreground="Red">
</Button>
在设计师视图中,我看到了变化。但在运行期间,这些更改不会应用。
经过一番调查后,我还有一个Style for all TextBlock,如下所示:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Segoe UI Semibold" />
<Setter Property="Foreground" Value="White" />
</Style>
此样式似乎会覆盖Button上使用的TextBlock。我仍然无法更改XAML中的文本属性。
如果我在空项目中使用上面的样式,那么它就是这样的:
在设计器中,应用更改,在运行期间应用TextBlock中的更改。如果我将一个x:Key分配给TextBlock,它可以正常工作。但是我必须手动将此样式分配给应用程序中使用的每个TextBlock。
答案 0 :(得分:1)
您在wpf中遇到典型的样式继承问题。
控件在初始化时查找其样式。控件查找其样式的方式是在逻辑树中向上移动,并询问逻辑父级是否存在父级资源字典中存储的适当样式。
在您的情况下,您在按钮中使用ContentPresenter作为默认行为。并且它默认使用TextBlock来表示按钮中的文本。
因此,在初始化时,ContentPresenter会查找TextBlock样式并应用于在按钮中表示内容。
如果要限制ContentPresenter查找样式,则必须将空白样式绑定到内容展示器,以便它不会查找任何其他样式。
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="StatusButtonCircle" Stroke="Black" StrokeThickness="0" Fill="AliceBlue" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircle" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<Ellipse x:Name="StatusButtonCircleHighlight" Margin="4" Stroke="Black" StrokeThickness="2" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircleHighlight" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock" BasedOn="{x:Null}"/>
<!-- Assigned Blank style here therefore it will not search for any further style-->
</ContentPresenter.Resources>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
答案 1 :(得分:0)
首先,要复制此问题,需要在Style
中设置ResourceDictionary
,然后将其添加到Application.Resources
(精确TextBlock
全局样式)。在例如Style
内设置Window.Resources
不会重现该问题。
正如问题中所提到的,问题是Style
的全局(无密钥)TextBlock
在{I}结束内容时应用于TextBlock
创建的ContentPresenter
显示是一个字符串。由于某些原因,在Style
内定义Window.Resources
时不会发生这种情况。事实证明,除此之外,还有“控件正在父母资源中寻找自己的风格”。
对于TextBlock
中的Control
(不是来自UIElement
类,而是来自ControlTemplate
),这意味着wpf 不会查找它隐含Style
超出它是模板化的父级。因此,它不会在其父资源中查找隐式Style
,它将应用Style
中找到的应用程序级隐式Application.Resources
。
这是设计(如果你愿意,硬编码到FrameworkElement
),原因正是为了防止像这样的问题。假设您正在创建一个特定的Button
设计(就像您一样),并且您希望应用程序中的所有按钮都使用该设计,甚至是其他ControlTemplate
中的按钮。好吧,他们可以Button
来自Control
。另一方面,您不希望所有使用TextBlock
的控件呈现文本,以应用隐式TextBlock
Style
。您将使用ComboBox
,Label
来解决相同的问题...因为他们都使用TextBlock
,而不只是Button
。
所以结论是:不要为Style
,中的Control
类派生的元素定义全局Application.Resources
,除非您100%确定这是什么你想要(例如将其移至Window.Resources
)。或者,引用我在MahApps.Metro
UI库的源代码中找到的评论:“永远不要在App.xaml中为TextBlock创建默认样式!!!”。您可以使用某种解决方案为TextBlock
Button
ControlTemplate
中的Label
添加样式,但是您必须为ComboBox
,new_york_data <- geo.lookup(state = "NY", place = "New York")
prep_data <- function(full_data){
output <- data.frame()
for(row in 1:nrow(full_data)){
new_rows <- replicateCounty(full_data[row, ])
output <- plyr::rbind.fill(output, new_rows)
}
return(output)
}
replicateCounty <- function(row){
counties <- str_trim(unlist(str_split(row$county.name, ",")))
output <- data.frame(state = row$state,
state.name = row$state.name,
county.name = counties,
place = row$place,
place.name = row$place.name)
return(output)
}
prep_data(new_york_data)
执行此操作,等等......所以,就是不要。