XAML, 将两个contentcontrol 移到带有动画的按钮内
XAML, move two contentcontrol inside a button with animation
是否可以在按钮内移动两个内容控件并调整该按钮的大小?
<Button Height="100" Width="100">
<Grid>
<Grid.RowDefinitions>
<RowDefinition height="30"/>
<RowDefinition height="30"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="img.jpg"/>
<TextBlock Grid.Row="1" Text="Some content"/>
</Grid>
</Button>
我想在 MouseOver 上将它们水平对齐而不是垂直对齐,并将按钮的大小从 100 调整为 50,这可能吗?
这可以用一种风格来实现:
<Style x:Key="ExampleButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Height" Value="100"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<UniformGrid x:Name="uGrid">
<Image Source="img.jpg" />
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</UniformGrid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="false">
<Setter TargetName="uGrid" Property="Rows" Value="2" />
<Setter TargetName="uGrid" Property="Columns" Value="1" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="uGrid" Property="Columns" Value="2" />
<Setter TargetName="uGrid" Property="Rows" Value="1" />
<Setter Property="Height" Value="50" />
<Setter Property="Width" Value="50" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
此样式为您的按钮定义了修改后的模板,并且可以利用触发器来响应鼠标事件。
要将样式添加到您的按钮,请执行以下操作:
<Grid>
<Grid.Resources>
<!-- Put Style Here -->
</Grid.Resources>
<Button Style="{DynamicResource ExampleButtonStyle}">
<TextBlock Grid.Row="1" Text="Some content"/>
</Button>
</Grid>
如何在样式和控件实例之间分配代码由您决定。您可能希望保持模块化和可重复使用。
风格剖析
如果您以前没有探索过样式,它们可能会有点令人生畏和冗长。我已经在下面解释了所提供样式的组件。
您可以通过声明样式来开始一种新样式。在这里你必须指定一个目标类型(你想要将样式应用到什么)和一个键(样式资源的名称:
<Style x:Key="ExampleButtonStyle" TargetType="{x:Type Button}">
<!-- Style content goes here. -->
</Style>
Setter 用于使样式将值应用于目标控件的属性。例如:
<Setter Property="Background" Value="LightGray"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Height" Value="100"/>
<Setter Property="Width" Value="100"/>
因为要改变按钮的布局,所以要指定一个控件模板。为此,请使用 Setter 设置按钮的模板 属性。此处的模板可以包含您想要的任何布局。 ContentPresenter 用于显示您的实现中 Button 标记的主体:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<UniformGrid x:Name="uGrid">
<Image Source="img.jpg" />
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</UniformGrid>
</Border>
<ControlTemplate.Triggers>
<!-- Triggers here -->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
最后,您需要添加触发器,使控件模板随着交互而更新。触发器本质上观察控件的 属性 ,并在其值与触发器指定的值匹配时应用。这将使用其中的设置器更新控件。
<Trigger Property="IsMouseOver" Value="false">
<Setter TargetName="uGrid" Property="Rows" Value="2" />
<Setter TargetName="uGrid" Property="Columns" Value="1" />
</Trigger>
布局
为了实现您的布局目标,我使用了 UniformGrid。 UniformGrid 将自己划分为相等的单元格以匹配其中内容项的数量。请注意,这在 WPF 中可用,但在 UWP 中不可用。在 UniformGrid 上,您可以设置列数或行数,网格将根据需要进行补偿。在上面的样式中,我正在更改指定的行数和列数,并让网格相应地调整自身布局。这在视觉上将内容从行交换到列。
担忧
还有其他方法可以更优雅地实现这一点,但样式提供了很大的灵活性,并且学习曲线更短。
您说您想将按钮大小从 100 更改为 50(我假设在两个轴上?)我必须建议您不要这样做。当您应用提供的样式时,您将看到会发生什么;该按钮以 100x100 正方形开始。用户将鼠标移到按钮上,刚好在按钮的边缘内。按钮迅速从 50x50 变为 100x100,直到鼠标移动到中心或完全离开按钮。这提供了糟糕且令人困惑的用户体验,值得更多思考。
这可能晚了,但根据评论中的说法,这可以解决问题,我最近在做类似的事情
<Style x:Key="btnSubMenu" TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="FontWeight" Value="ExtraBold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid x:Name="uGrid2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="/Images/1.png" />
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Grid Grid.Row="2" Name="Gbexample" Visibility="Collapsed">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Style="{DynamicResource btnSubSubMenu}" Content="{DynamicResource strCity}" Name="btnCity"/>
<Button Grid.Row="1" Style="{DynamicResource btnSubSubMenu}" Content="{DynamicResource strCountry}" Name="btnCountry"/>
<Button Grid.Row="2" Style="{DynamicResource btnSubSubMenu}" Content="{DynamicResource strStore}" Name="btnStoreIn"/>
<Button Grid.Row="3" Style="{DynamicResource btnSubSubMenu}" Content="{DynamicResource strLocation}" Name="btnLocation"/>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="false">
<Setter TargetName="Gbproduct" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Gbproduct" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
是否可以在按钮内移动两个内容控件并调整该按钮的大小?
<Button Height="100" Width="100">
<Grid>
<Grid.RowDefinitions>
<RowDefinition height="30"/>
<RowDefinition height="30"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="img.jpg"/>
<TextBlock Grid.Row="1" Text="Some content"/>
</Grid>
</Button>
我想在 MouseOver 上将它们水平对齐而不是垂直对齐,并将按钮的大小从 100 调整为 50,这可能吗?
这可以用一种风格来实现:
<Style x:Key="ExampleButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Height" Value="100"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<UniformGrid x:Name="uGrid">
<Image Source="img.jpg" />
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</UniformGrid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="false">
<Setter TargetName="uGrid" Property="Rows" Value="2" />
<Setter TargetName="uGrid" Property="Columns" Value="1" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="uGrid" Property="Columns" Value="2" />
<Setter TargetName="uGrid" Property="Rows" Value="1" />
<Setter Property="Height" Value="50" />
<Setter Property="Width" Value="50" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
此样式为您的按钮定义了修改后的模板,并且可以利用触发器来响应鼠标事件。
要将样式添加到您的按钮,请执行以下操作:
<Grid>
<Grid.Resources>
<!-- Put Style Here -->
</Grid.Resources>
<Button Style="{DynamicResource ExampleButtonStyle}">
<TextBlock Grid.Row="1" Text="Some content"/>
</Button>
</Grid>
如何在样式和控件实例之间分配代码由您决定。您可能希望保持模块化和可重复使用。
风格剖析
如果您以前没有探索过样式,它们可能会有点令人生畏和冗长。我已经在下面解释了所提供样式的组件。
您可以通过声明样式来开始一种新样式。在这里你必须指定一个目标类型(你想要将样式应用到什么)和一个键(样式资源的名称:
<Style x:Key="ExampleButtonStyle" TargetType="{x:Type Button}">
<!-- Style content goes here. -->
</Style>
Setter 用于使样式将值应用于目标控件的属性。例如:
<Setter Property="Background" Value="LightGray"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Height" Value="100"/>
<Setter Property="Width" Value="100"/>
因为要改变按钮的布局,所以要指定一个控件模板。为此,请使用 Setter 设置按钮的模板 属性。此处的模板可以包含您想要的任何布局。 ContentPresenter 用于显示您的实现中 Button 标记的主体:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<UniformGrid x:Name="uGrid">
<Image Source="img.jpg" />
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</UniformGrid>
</Border>
<ControlTemplate.Triggers>
<!-- Triggers here -->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
最后,您需要添加触发器,使控件模板随着交互而更新。触发器本质上观察控件的 属性 ,并在其值与触发器指定的值匹配时应用。这将使用其中的设置器更新控件。
<Trigger Property="IsMouseOver" Value="false">
<Setter TargetName="uGrid" Property="Rows" Value="2" />
<Setter TargetName="uGrid" Property="Columns" Value="1" />
</Trigger>
布局
为了实现您的布局目标,我使用了 UniformGrid。 UniformGrid 将自己划分为相等的单元格以匹配其中内容项的数量。请注意,这在 WPF 中可用,但在 UWP 中不可用。在 UniformGrid 上,您可以设置列数或行数,网格将根据需要进行补偿。在上面的样式中,我正在更改指定的行数和列数,并让网格相应地调整自身布局。这在视觉上将内容从行交换到列。
担忧
还有其他方法可以更优雅地实现这一点,但样式提供了很大的灵活性,并且学习曲线更短。
您说您想将按钮大小从 100 更改为 50(我假设在两个轴上?)我必须建议您不要这样做。当您应用提供的样式时,您将看到会发生什么;该按钮以 100x100 正方形开始。用户将鼠标移到按钮上,刚好在按钮的边缘内。按钮迅速从 50x50 变为 100x100,直到鼠标移动到中心或完全离开按钮。这提供了糟糕且令人困惑的用户体验,值得更多思考。
这可能晚了,但根据评论中的说法,这可以解决问题,我最近在做类似的事情
<Style x:Key="btnSubMenu" TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="FontWeight" Value="ExtraBold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<Grid x:Name="uGrid2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="/Images/1.png" />
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Grid Grid.Row="2" Name="Gbexample" Visibility="Collapsed">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Style="{DynamicResource btnSubSubMenu}" Content="{DynamicResource strCity}" Name="btnCity"/>
<Button Grid.Row="1" Style="{DynamicResource btnSubSubMenu}" Content="{DynamicResource strCountry}" Name="btnCountry"/>
<Button Grid.Row="2" Style="{DynamicResource btnSubSubMenu}" Content="{DynamicResource strStore}" Name="btnStoreIn"/>
<Button Grid.Row="3" Style="{DynamicResource btnSubSubMenu}" Content="{DynamicResource strLocation}" Name="btnLocation"/>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="false">
<Setter TargetName="Gbproduct" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Gbproduct" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>