2016-11-15 1 views
2

У меня есть кнопка с изображением и текстовым блоком. Кнопки создаются динамически на основе значений из базы данных. Теперь для определенного значения присутствует текст, и нет изображения. Я хочу показать этот текст в центре кнопки (по горизонтали и вертикали), но он не работает.Как сделать текст текстового блока в центре кнопки с изображением и текстом, если в WPF нет изображения.

Пожалуйста, найдите ниже 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

Вы можете использовать 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; } 
} 

Создать и инициализировать ButtonTemplateSelector ресурса в XAML, а затем сослаться на него из вашего 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

+0

Есть и другие варианты - например, вы жёстко высоту изображения. Если вместо этого вы указали высоту кнопки, часть изображения может упасть в ничто, и вы останетесь с вертикально центрированной строкой. Зависит от ваших данных, хотя ... –

+0

Спасибо за ответ Питер. Вы поняли, чего я хочу, но у меня мало вопросов, если вы могли бы помочь мне. –

+0

Конечно, я отдам. (Если вам нравится ответ, подумайте о его принятии.) –

Смежные вопросы