这可以通过样式来实现:
<Style x:Key="ExampleButtonStyle" TargetType="">
<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="">
<Border x:Name="border" BorderBrush="" BorderThickness="" Background="" SnapsToDevicePixels="true">
<UniformGrid x:Name="uGrid">
<Image Source="img.jpg" />
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="" Margin="" RecognizesAccessKey="True" SnapsToDevicePixels="" VerticalAlignment=""/>
</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>
<!
</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将按钮的Template属性设置为所需的模板。此处的模板可以包含任何您想要的布局。 ContentPresenter用于显示您实现中Button标记的正文:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="">
<Border x:Name="border" BorderBrush="" BorderThickness="" Background="" SnapsToDevicePixels="true">
<UniformGrid x:Name="uGrid">
<Image Source="img.jpg" />
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="" Margin="" RecognizesAccessKey="True" SnapsToDevicePixels="" VerticalAlignment=""/>
</UniformGrid>
</Border>
<ControlTemplate.Triggers>
<!-- Triggers here -->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
最后,您需要添加触发器以使控件模板随交互更新。触发器本质上观察控件的属性,并在其值与触发器指定的值相匹配时应用。这将使用其中的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,直到将鼠标移到中心或完全移出按钮。这会导致糟糕和混乱的用户体验,需要更多的思考。