以编程方式使用Canvas创建按钮

时间:2018-05-25 09:01:12

标签: c# wpf canvas path

我在按钮样式中遇到了画布的可见性问题。 我动态创建一个stackPanel,里面有两个按钮,用于集合中的每个项目。问题是只有最后一项的按钮与其画布一起出现,之前的按钮不再出现。

风格

    <!-- Delete Dictionnary -->
<ControlTemplate x:Key="PathDelete">
    <Canvas x:Name="appbar_delete" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
        <Path Width="27.7083" Height="35.625" Canvas.Left="24.1458" Canvas.Top="19.7917" Stretch="Fill" 
              Data="F1 M 25.3333,23.75L 50.6667,23.75C 51.5411,23.75 51.8541,27.3125 51.8541,27.3125L 24.1458,27.3125C 24.1458,27.3125 24.4589,23.75 25.3333,23.75 Z M 35.625,19.7917L 40.375,19.7917C 40.8122,19.7917 41.9583,20.9378 41.9583,21.375C 41.9583,21.8122 40.8122,22.9584 40.375,22.9584L 35.625,22.9584C 35.1878,22.9584 34.0416,21.8122 34.0416,21.375C 34.0416,20.9378 35.1878,19.7917 35.625,19.7917 Z M 27.7083,28.5L 48.2916,28.5C 49.1661,28.5 49.875,29.2089 49.875,30.0834L 48.2916,53.8334C 48.2916,54.7078 47.5828,55.4167 46.7083,55.4167L 29.2917,55.4167C 28.4172,55.4167 27.7083,54.7078 27.7083,53.8334L 26.125,30.0834C 26.125,29.2089 26.8339,28.5 27.7083,28.5 Z M 30.0833,31.6667L 30.4792,52.25L 33.25,52.25L 32.8542,31.6667L 30.0833,31.6667 Z M 36.4167,31.6667L 36.4167,52.25L 39.5833,52.25L 39.5833,31.6667L 36.4167,31.6667 Z M 43.1458,31.6667L 42.75,52.25L 45.5208,52.25L 45.9167,31.6667L 43.1458,31.6667 Z "/>
    </Canvas>
</ControlTemplate>

<!-- Button Style Dictionnary -->   
<Style x:Key="StackPanelLightButton" TargetType="{x:Type Button}">
    <Style.Resources>
        <Style TargetType="{x:Type Path}">
            <Setter Property="OverridesDefaultStyle" Value="True"/>
            <Setter Property="Fill" Value="White"/>
        </Style>
    </Style.Resources>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="Margin" Value="2,0,0,0"/>
    <Setter Property="Tag" Value=""/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid Background="{x:Null}" Width="26" Height="26" SnapsToDevicePixels="True">
                    <Border Name="Border" BorderThickness="0" CornerRadius="4,0,4,0"
                            Background="Green" 
                            BorderBrush="{StaticResource BtnDatagridContentBrush}">
                        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
                            <Viewbox Stretch="Uniform">
                                <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}"/>
                            </Viewbox>
                        </Grid>
                    </Border>
                    <Border Name="BorderFront" BorderThickness="0" CornerRadius="1" Panel.ZIndex="10"
                            Background="Transparent"  
                            BorderBrush="{x:Null}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

    <!--BntDelete-->
<Style x:Key="BtnDeleteStackPanelStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource StackPanelLightButton}" x:Shared="False">
    <Setter Property="Content">
        <Setter.Value>
            <Control Template="{StaticResource PathDelete}">
                <Control.Resources>
                    <Style TargetType="{x:Type Path}" BasedOn="{StaticResource {x:Type Path}}"/>
                </Control.Resources>
            </Control>
        </Setter.Value>
    </Setter>
</Style

创建代码

    Style bntStyle = this.FindResource("BtnAlbumWrapPanelStyle") as Style;
Style bntSuppStyle = this.FindResource("BtnDeleteStackPanelStyle") as Style;
double width = Album_Panel.ActualWidth - 50;
Thickness margin = new Thickness() { Left = 10, Top = 0, Right = 0, Bottom = 0 };
Thickness marginSupp = new Thickness() { Left = 5, Top = 2, Right = 2, Bottom = 2 };
Thickness marginStack = new Thickness() { Left = 0, Top = 10, Right = 0, Bottom = 2 };

foreach (Album item in ListAlbum)
{
    StackPanel myStackPanel = new StackPanel()
    {
        Orientation = Orientation.Horizontal,
        Margin = marginStack
    };

    Button bnt = new Button()
    {
        HorizontalAlignment = HorizontalAlignment.Center,
        Width = width,
        Margin = margin,
        Style = bntStyle,
        HorizontalContentAlignment = HorizontalAlignment.Left,
        VerticalAlignment = VerticalAlignment.Center,
        Content = item.FullName,
        Tag = item,
    };
    bnt.Click += new RoutedEventHandler(btn_Click);

    Button bntSupp = new Button()
    {
        HorizontalAlignment = HorizontalAlignment.Left,
        VerticalAlignment = VerticalAlignment.Center,
        Width = 30,
        Height = 30,
        Margin = marginSupp,
        Style = bntSuppStyle,
        Visibility = Visibility.Visible,
        Tag = item,
    };
    bntSupp.Click += new RoutedEventHandler(btnSupp_Click);
    myStackPanel.Children.Add(bnt);
    myStackPanel.Children.Add(bntSupp);
    Album_Panel.Children.Add(myStackPanel);
}

Visual

你会看到我的错误吗?

1 个答案:

答案 0 :(得分:1)

这个二传手

<Setter Property="Content">
    <Setter.Value>
        <Control Template="{StaticResource PathDelete}">
            <Control.Resources>
                <Style TargetType="{x:Type Path}" BasedOn="{StaticResource {x:Type Path}}"/>
            </Control.Resources>
        </Control>
    </Setter.Value>
</Setter>

仅创建Control的一个实例,由所有按钮共享。显然,控制实例不能同时定位在多个位置。

将控件转换为资源,使用x:Shared =&#34; False&#34; 创建多个实例

<Control Template="{StaticResource PathDelete}" x:Key="DelContent" x:Shared="False">
    <Control.Resources>
        <Style TargetType="{x:Type Path}" BasedOn="{StaticResource {x:Type Path}}"/>
    </Control.Resources>
</Control>

并在setter中使用Resource

<Style x:Key="BtnDeleteStackPanelStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource StackPanelLightButton}" x:Shared="False">
    <Setter Property="Content" Value="{StaticResource DelContent}"/>
</Style

另外:您可以使用ItemsControl来显示ListAlbum集合,而不是在代码隐藏中构建动态元素。这是an example