在XAML页面上放置不同元素的最方便方法是什么?

dced5bon  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(137)

我是XAML和WPF的新手,到目前为止,我在SO上找到了很多很好的解释,可以解释我在项目工作中所需要的不同东西。我来自网络领域,在那里我有很多使用CSS为网页制作图形元素布局的经验。真正让我沮丧的是,当我得到一个模拟文件(如附件所示)时,我不知道如何在WPF页面中制作一些自定义的漂亮UI。
特别是这个文件,我需要放置左边有边框,右边有一个正方形的按钮。这两个按钮的颜色取决于按钮的状态。如果按钮被按下,左边边框和右边正方形的颜色应该是绿色的(如屏幕截图所示)。
有没有类似或至少接近CSS的方法,我可以用来实现这一点?

kiayqfof

kiayqfof1#

您的一般布局建议您有一个状态集合,您希望将其表示为按钮列表。这些按钮应该是可切换的,并且在切换时显示绿色。在这种情况下,ItemsControl将是合适的,因为您不希望或需要选择,而是与按钮交互。
对于按钮本身,还有很多工作要做。可视化表示和状态在控件模板中定义。您可以从头开始创建一个新的,也可以在copy the default control template中对其进行修改。这里我为ToggleButton创建了一个控件模板,它反映了您的模型。

<Style x:Key="FocusVisual">
   <Setter Property="Control.Template">
      <Setter.Value>
         <ControlTemplate>
            <Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="Black"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="LawnGreen"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="Black"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="DarkGreen"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="Black"/>
<SolidColorBrush x:Key="Button.IsChecked.Background" Color="Green"/>
<SolidColorBrush x:Key="Button.IsChecked.Border" Color="Black"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<Style x:Key="ToggleButtonStyle" TargetType="{x:Type ToggleButton}">
   <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
   <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
   <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
   <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
   <Setter Property="BorderThickness" Value="1"/>
   <Setter Property="HorizontalContentAlignment" Value="Center"/>
   <Setter Property="VerticalContentAlignment" Value="Center"/>
   <Setter Property="Padding" Value="1"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type ToggleButton}">
            <Grid>
               <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="Auto"/>
                  <ColumnDefinition/>
                  <ColumnDefinition Width="Auto"/>
               </Grid.ColumnDefinitions>
               <Rectangle x:Name="Lr"  Grid.Column="0" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="{TemplateBinding BorderThickness}" Width="20" Height="40"/>
               <Border x:Name="Bd" Grid.Column="1" Background="Transparent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
                  <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
               </Border>
               <Rectangle x:Name="Rr" Grid.Column="2" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="{TemplateBinding BorderThickness}" Width="40" Height="40" Margin="40, 0, 0, 0"/>
            </Grid>
            <ControlTemplate.Triggers>
               <Trigger Property="Button.IsDefaulted" Value="true">
                  <Setter Property="BorderBrush" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
               </Trigger>
               <Trigger Property="IsMouseOver" Value="true">
                  <Setter Property="Fill" TargetName="Lr" Value="{StaticResource Button.MouseOver.Background}"/>
                  <Setter Property="Fill" TargetName="Rr" Value="{StaticResource Button.MouseOver.Background}"/>
                  <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Button.MouseOver.Border}"/>
                  <Setter Property="Stroke" TargetName="Lr" Value="{StaticResource Button.MouseOver.Border}"/>
                  <Setter Property="Stroke" TargetName="Rr" Value="{StaticResource Button.MouseOver.Border}"/>
               </Trigger>
               <Trigger Property="IsPressed" Value="true">
                  <Setter Property="Fill" TargetName="Lr" Value="{StaticResource Button.Pressed.Background}"/>
                  <Setter Property="Fill" TargetName="Rr" Value="{StaticResource Button.Pressed.Background}"/>
                  <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Button.Pressed.Border}"/>
                  <Setter Property="Stroke" TargetName="Lr" Value="{StaticResource Button.Pressed.Border}"/>
                  <Setter Property="Stroke" TargetName="Rr" Value="{StaticResource Button.Pressed.Border}"/>
               </Trigger>
               <Trigger Property="IsChecked" Value="true">
                  <Setter Property="Fill" TargetName="Lr" Value="{StaticResource Button.IsChecked.Background}"/>
                  <Setter Property="Fill" TargetName="Rr" Value="{StaticResource Button.IsChecked.Background}"/>
                  <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Button.IsChecked.Border}"/>
                  <Setter Property="Stroke" TargetName="Lr" Value="{StaticResource Button.IsChecked.Border}"/>
                  <Setter Property="Stroke" TargetName="Rr" Value="{StaticResource Button.IsChecked.Border}"/>
               </Trigger>
               <Trigger Property="IsEnabled" Value="false">
                  <Setter Property="Fill" TargetName="Lr" Value="{StaticResource Button.Disabled.Background}"/>
                  <Setter Property="Fill" TargetName="Rr" Value="{StaticResource Button.Disabled.Background}"/>
                  <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Button.Disabled.Border}"/>
                  <Setter Property="Stroke" TargetName="Lr" Value="{StaticResource Button.Disabled.Border}"/>
                  <Setter Property="Stroke" TargetName="Rr" Value="{StaticResource Button.Disabled.Border}"/>
                  <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
               </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

本质上,控件模板由GridContentPresenter组成,其中Grid承载两个用于显示状态颜色的矩形,ContentPresenter位于这两个矩形之间,用于显示内容。不同的状态有不同的触发器,它们相应地设置矩形的颜色。当IsCheckedtrue时,切换的状态是活动的,当您在按钮上按下鼠标按钮时,IsPressed是活动的。
如需如何建立自订控件样板的详细信息,请参阅文件集。

现在需要创建一个ItemsControl,绑定集合并添加一个DataTemplate。数据模板定义了数据项的表示方式,请参见Data Templating Overview

<DockPanel>
   <Border DockPanel.Dock="Top"
           BorderBrush="Black"
           BorderThickness="1"
           Margin="0, 0, 0, 40">
      <TextBlock Text="States"
                 TextAlignment="Center"/>
   </Border>
   <ScrollViewer>
      <ItemsControl ItemsSource="{Binding StringItems}">
         <ItemsControl.ItemTemplate>
            <DataTemplate>
               <ToggleButton Content="{Binding}"
                             Style="{StaticResource ToggleButtonStyle}"/>
            </DataTemplate>
         </ItemsControl.ItemTemplate>
      </ItemsControl>
   </ScrollViewer>
</DockPanel>

就是这样,结果如下:

相关问题