如果WPF中没有可用的图像,如何使文本块文本居中于带图像和文本的按钮

时间:2016-11-15 12:53:18

标签: xaml imagebutton

我有一个带图像和文本块的按钮。 按钮是根据数据库中的值动态创建的。 现在,对于特定值,文本存在且没有图像在那里我想在按钮的中心(水平和垂直)显示该文本,但它不起作用。

请找到下面的xaml:

<ItemsControl ItemsSource="{Binding CategoriesList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Width="100" Margin="5" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
                <Button.Template>
                    <ControlTemplate>
                        <Border CornerRadius="10" Background="Maroon">
                            <StackPanel Orientation="Vertical">
                                <Image Source="{Binding CategoryImagePath}" Height="50"></Image>
                                <TextBlock Text="{Binding CategoryName}" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
                            </StackPanel>
                        </Border>
                    </ControlTemplate>
                </Button.Template>
            </Button>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

如果没有可用的图像,我想只显示按钮上的文字,但它应该居中。

如果有图像,那么我会显示图像和文本,但是当图像不可用时,文本会显示但不在中心它移动到按钮的顶部。

1 个答案:

答案 0 :(得分:1)

您可以使用DataTemplateSelector根据您是否拥有图片来选择不同的模板。这样的选择器可能如下所示:

public sealed class ButtonTemplateSelector : DataTemplateSelector
{
    /// <summary>
    /// Gets or sets the <see cref="DataTemplate"/> to use when we have an image.
    /// The value is set in XAML.
    /// </summary>
    public DataTemplate ImageTemplate { get; set; }

    /// <summary>
    /// Gets or sets the <see cref="DataTemplate"/> to use when we don't have an image.
    /// The value is set in XAML.
    /// </summary>
    public DataTemplate NoImageTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        Category category = item as Category;
        if (category != null)
        {
            return category.CategoryImagePath == null ? NoImageTemplate : ImageTemplate;
        }

        return base.SelectTemplate(item, container);
    }
}

我假设模型对象是这样的:

public class Category
{
    public string CategoryImagePath { get; set; }

    public string CategoryName { get; set; }
}

在您的XAML中创建并初始化ButtonTemplateSelector资源,然后从ItemsControl引用它:

<Window
    x:Class="WPF.MainWindow"
    x:Name="self"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:wpf="clr-namespace:WPF"
    mc:Ignorable="d"
    Title="MainWindow"
    Height="350"
    Width="525">
    <Grid>
        <Grid.Resources>
            <wpf:ButtonTemplateSelector x:Key="ButtonTemplateSelector">
                <wpf:ButtonTemplateSelector.ImageTemplate>
                    <DataTemplate DataType="wpf:Category">
                        <Button
                            Width="100"
                            Margin="5"
                            HorizontalContentAlignment="Center"
                            VerticalContentAlignment="Center">
                            <Button.Template>
                                <ControlTemplate>
                                    <Border CornerRadius="10" Background="Maroon">
                                        <StackPanel Orientation="Vertical">
                                            <Image
                                                Source="{Binding CategoryImagePath}"
                                                Height="50" />
                                            <TextBlock
                                                Foreground="White"
                                                Text="{Binding CategoryName}"
                                                Height="20"
                                                HorizontalAlignment="Center"
                                                VerticalAlignment="Center" />
                                        </StackPanel>
                                    </Border>
                                </ControlTemplate>
                            </Button.Template>
                        </Button>
                    </DataTemplate>
                </wpf:ButtonTemplateSelector.ImageTemplate>
                <wpf:ButtonTemplateSelector.NoImageTemplate>
                    <DataTemplate DataType="wpf:Category">
                        <Button
                            Width="100"
                            Margin="5"
                            HorizontalContentAlignment="Center"
                            VerticalContentAlignment="Center">
                            <Button.Template>
                                <ControlTemplate>
                                    <Border
                                        CornerRadius="10"
                                        Background="Maroon"
                                        Height="70">
                                        <TextBlock
                                            Foreground="White"
                                            Text="{Binding CategoryName}"
                                            Height="20"
                                            HorizontalAlignment="Center"
                                            VerticalAlignment="Center" />
                                    </Border>
                                </ControlTemplate>
                            </Button.Template>
                        </Button>
                    </DataTemplate>
                </wpf:ButtonTemplateSelector.NoImageTemplate>
            </wpf:ButtonTemplateSelector>
        </Grid.Resources>
        <ItemsControl
            DataContext="{Binding ElementName=self}"
            ItemsSource="{Binding CategoriesList}"
            ItemTemplateSelector="{StaticResource ButtonTemplateSelector}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Grid>
</Window>

为了完整性,窗口的代码隐藏:

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public IEnumerable<Category> CategoriesList { get; } = new List<Category>
        {
            new Category { CategoryName = "First", CategoryImagePath = "/Assets/Square.bmp" },
            new Category { CategoryName = "Second", CategoryImagePath = null },
        };
}

这显示如下,我认为这就是你所要求的:

My image is a red square