Как привязать иконку кнопки к выбранному элементу выпадающего списка?

В приложении WPF и с помощью Fluent Ribbon Control Suite у меня есть DropDownButton, который открывает галерею, позволяющую пользователю выбрать цвет.

Приложение 1

Вот XAML, который создает кнопку:

<Fluent:DropDownButton x:Name="btnCommentColor" Header="Comments">
<Fluent:DropDownButton.Icon>
    <!-- What goes here? -->
</Fluent:DropDownButton.Icon>
<Fluent:Gallery x:Name="galCommentColor" ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}" SelectedValuePath="Name" MaxItemsInRow="12">
    <Fluent:Gallery.ItemTemplate>
        <DataTemplate>
            <Border BorderThickness="1" CornerRadius="2" BorderBrush="Black" Width="25" Height="25" VerticalAlignment="Stretch" Background="{Binding Name}" /> 
        </DataTemplate>
    </Fluent:Gallery.ItemTemplate>
</Fluent:Gallery>
</Fluent:DropDownButton>

SelectedItem галереи возвращает имя цвета. Я хочу, чтобы значок кнопки отображал фактический выбранный цвет. Можно ли это сделать исключительно с помощью XAML? Я пробовал разные вещи, найденные в Интернете, но до сих пор не смог получить ничего, кроме названия цвета, которое появилось там, где я хочу, чтобы цветной прямоугольник шел. Ищите «Что здесь происходит?» в XAML выше.

Я ценю любые полезные предложения. Спасибо за чтение!

ОБНОВИТЬ:

Я попробовал ответ, приведенный ниже, и он все еще не работает. У меня должно быть что-то не так. Вот обновленный список всего кода XAML для этой кнопки. Взгляните на XAML для самой галереи и привязку для SolidColorBrush и сообщите мне, если вы видите, что я сделал неправильно.

<Window.Resources>
    <ObjectDataProvider MethodName="GetType" 
     ObjectType="{x:Type sys:Type}" x:Key="colorsTypeOdp">
        <ObjectDataProvider.MethodParameters>
            <sys:String>System.Windows.Media.Colors, PresentationCore,  
             Version=3.0.0.0, Culture=neutral,  
             PublicKeyToken=31bf3856ad364e35</sys:String>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>

    <ObjectDataProvider ObjectInstance="{StaticResource colorsTypeOdp}" 
     MethodName="GetProperties" x:Key="colorPropertiesOdp">
    </ObjectDataProvider>
</Window.Resources>

<Fluent:DropDownButton Name="btnCommentColor" Header="Comments">
    <Fluent:DropDownButton.LargeIcon>
        <Grid Width="32" Height="32">
            <Image Source="Icons\BlueLarge.png" />
            <Border Height="32" VerticalAlignment="Bottom" BorderThickness="0" CornerRadius="2">
                <Border.Background>
                    <SolidColorBrush Color="{Binding ElementName=galCommentColor, Path=SelectedValue, FallbackValue=Green}" />
                </Border.Background> 
            </Border>
        </Grid>
    </Fluent:DropDownButton.LargeIcon>
    <Fluent:Gallery Name="galCommentColor" ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}" SelectedValuePath="Name" MaxItemsInRow="12">
        <Fluent:Gallery.ItemTemplate>
            <DataTemplate>
                <Border ToolTip="{Binding Path=Name}" BorderThickness="1" CornerRadius="2" BorderBrush="Black" Width="25" Height="25" VerticalAlignment="Stretch" Background="{Binding Name}" /> 
            </DataTemplate>
        </Fluent:Gallery.ItemTemplate>
    </Fluent:Gallery>
</Fluent:DropDownButton>

person tolsen64    schedule 20.09.2013    source источник


Ответы (2)


На странице 17 пошагового руководства приведен пример того, чего вы пытаетесь достичь.

Вы можете скачать его здесь: http://fluent.codeplex.com/documentation

Взято из прохождения:

введите здесь описание изображения

<fluent1:Ribbon>
    <fluent1:Ribbon.Menu>
        <fluent1:Backstage />
    </fluent1:Ribbon.Menu>
    <fluent1:RibbonTabItem Header="Home">
        <fluent1:RibbonGroupBox Header="Clipboard">
            <!--  The following code shows standard mode for color gallery  -->
            <fluent1:DropDownButton Header="Standard">
                <!--  It's possible to create custom icon to present selected color  -->
                <fluent1:DropDownButton.Icon>
                    <Grid Width="16" Height="16">
                        <Image Source="Images\FontColor.png" />
                        <Border Height="4"
                                VerticalAlignment="Bottom"
                                BorderThickness="0">
                            <Border.Background>
                                <SolidColorBrush
                                    Color="{Binding ElementName=ColorGalleryStandard, Path=SelectedColor, FallbackValue=Black}" />
                            </Border.Background>
                        </Border>
                    </Grid>
                </fluent1:DropDownButton.Icon>
                <fluent1:ColorGallery x:Name="ColorGalleryStandard"
                                        IsNoColorButtonVisible="False"
                                        SelectedColor="Red" />
                <fluent1:MenuItem Header="A Menu Item" Icon="Images\Pink.png" />
            </fluent1:DropDownButton>
        </fluent1:RibbonGroupBox>
    </fluent1:RibbonTabItem>
</fluent1:Ribbon>

ОБНОВЛЕНИЕ

Я не вижу ничего плохого в вашем коде, я вставил его, и он успешно запустился, вот он снова вставлен из моего рабочего теста.

<Window x:Class="WpfApplication8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:fluent1="clr-namespace:Fluent;assembly=Fluent"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Window.Resources>
        <ObjectDataProvider x:Key="colorsTypeOdp"
                            MethodName="GetType"
                            ObjectType="{x:Type system:Type}">
            <ObjectDataProvider.MethodParameters>
                <system:String>
                    System.Windows.Media.Colors, PresentationCore,
                    Version=3.0.0.0, Culture=neutral,
                    PublicKeyToken=31bf3856ad364e35
                </system:String>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

        <ObjectDataProvider x:Key="colorPropertiesOdp"
                            MethodName="GetProperties"
                            ObjectInstance="{StaticResource colorsTypeOdp}" />
    </Window.Resources>
    <fluent1:DropDownButton Name="btnCommentColor" Header="Comments">
        <fluent1:DropDownButton.LargeIcon>
            <Grid Width="32" Height="32">
                <Image Source="Icons\BlueLarge.png" />
                <Border Height="32"
                        VerticalAlignment="Bottom"
                        BorderThickness="0"
                        CornerRadius="2">
                    <Border.Background>
                        <SolidColorBrush
                            Color="{Binding ElementName=galCommentColor, Path=SelectedValue, FallbackValue=Green}" />
                    </Border.Background>
                </Border>
            </Grid>
        </fluent1:DropDownButton.LargeIcon>
        <fluent1:Gallery Name="galCommentColor"
                         ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}"
                         MaxItemsInRow="12"
                         SelectedValuePath="Name">
            <fluent1:Gallery.ItemTemplate>
                <DataTemplate>
                    <Border Width="25"
                            Height="25"
                            VerticalAlignment="Stretch"
                            Background="{Binding Name}"
                            BorderBrush="Black"
                            BorderThickness="1"
                            CornerRadius="2"
                            ToolTip="{Binding Path=Name}" />
                </DataTemplate>
            </fluent1:Gallery.ItemTemplate>
        </fluent1:Gallery>
    </fluent1:DropDownButton>

</Window>
person aybe    schedule 22.09.2013
comment
Спасибо. Я пробовал это. Это работает, если я использую ColorGallery, но я хочу использовать свою собственную галерею, которая отображает все System.Windows.Media.Color. Это мой XAML для кисти, но он не меняет цвет значка кнопки: ‹SolidColorBrush Color={Binding ElementName=galCommentColor, Path=SelectedValue, FallbackValue=Black} /›. Когда я MessageBox galCommentColor.SelectedValue.ToString, я получаю название цвета (например, DeepPink). - person tolsen64; 23.09.2013
comment
Обновил мой ответ, ваш код отлично работает для меня. Не знаете, что посоветовать, у вас последняя версия пакета Fluent от Nuget? - person aybe; 23.09.2013
comment
Я использую предварительную версию 2.1.0. Я попробую стабильную версию и посмотрю, будет ли это иметь значение. Спасибо, что помогли мне сохранить здравомыслие :) Я заставил его работать, используя событие кнопки DropDownClosed и установив цвет значка в коде... но я хочу сохранить все это XAML, если смогу. Спасибо еще раз. Пометка как принятый ответ. - person tolsen64; 24.09.2013
comment
Следует отметить одну вещь. Я создал преобразователь и добавил свойство преобразователя в элемент SolidColorBrush: Converter={StaticResource ColorNameToSolidColorBrushConverter}. Я добавил Debug.WriteLine в код конвертера, и я не вижу ничего, записанного в Debug, когда я выбираю цвет. Так что я даже не уверен, что он срабатывает при изменении выбора. - person tolsen64; 24.09.2013
comment
Определенно вы должны иметь возможность использовать только XAML, если вам не нужен конвертер. Если хотите, загрузите (небольшой) заархивированный проект с вашей проблемой куда-нибудь и дайте ссылку, я посмотрю. - person aybe; 24.09.2013
comment
Вот ссылка Я не включил все значки для других кнопки. Меня беспокоит только одна кнопка на вкладке «Цвета». Спасибо, что посмотрели. - person tolsen64; 24.09.2013
comment
Мне потребовалось всего несколько минут, чтобы найти причину, почти час, чтобы попытаться, но не исправить ... Из того, что я видел, проблема заключается во всплывающем окне цвета DropDownButton, привязка не может быть решена, поскольку всплывающие окна отделены от визуального дерева. Но вот два решения для вас: переместите группу цветов на первую вкладку, там она работает. Второе решение: найдите привязку к всплывающим окнам/задайте вопрос на свободном веб-сайте (вероятно, проще/лучше). Попробуйте посмотреть и их образцы. - person aybe; 24.09.2013
comment
Я сделал еще один тест, LargeIcon кажется глючным, потому что с Icon он работает. В своем коде попробуйте заменить DropDownButton.LargeIcon на Icon, затем установите DropDownButton.SizeDefinition=Middle, и вы увидите, что он работает (с отправленным вами кодом). Сообщите об ошибке на их сайте! - person aybe; 24.09.2013
comment
давайте продолжим это обсуждение в чате - person tolsen64; 24.09.2013

Спасибо Айбе за подтверждение, что это не я. Я получил желаемый результат, используя преобразователь свойства LargeIcon кнопки DropDownButton.

Вот XAML:

<Fluent:DropDownButton Name="btnCommentColor" Header="Comments" HasTriangle="False" LargeIcon="{Binding ElementName=galCommentColor, Path=SelectedValue, Converter={StaticResource ColorNameToBorderConverter_Key}}">
    <Fluent:Gallery x:Name="galCommentColor" ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}" SelectedValuePath="Name" MaxItemsInRow="12" SelectedIndex="51">
        <Fluent:Gallery.ItemTemplate>
            <DataTemplate>
                <Border ToolTip="{Binding Name}" BorderThickness="1" CornerRadius="2" BorderBrush="Black" Width="25" Height="25" VerticalAlignment="Stretch" Background="{Binding Name}" /> 
            </DataTemplate>
        </Fluent:Gallery.ItemTemplate>
    </Fluent:Gallery>
</Fluent:DropDownButton>

И код:

Public Class ColorNameToBorderConverter
    Implements IValueConverter

    Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
        If ApplicationIsInDesignMode Then value = "Black"

        If TypeOf value Is String Then
            Return New Border With {
                .Height = 32,
                .BorderThickness = New Thickness(1),
                .BorderBrush = New SolidColorBrush(System.Windows.Media.Colors.Black),
                .CornerRadius = New CornerRadius(2, 2, 2, 2),
                .VerticalAlignment = VerticalAlignment.Bottom,
                .Background = New SolidColorBrush(ColorConverter.ConvertFromString(value))
            }
        Else
            Throw New InvalidOperationException("Unsupported type [" & value.GetType.ToString & "]")
        End If
    End Function

    Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
        Throw New NotImplementedException
    End Function

    Private Shared ReadOnly Property ApplicationIsInDesignMode() As Boolean
        Get
            Return CBool(DesignerProperties.IsInDesignModeProperty.GetMetadata(GetType(DependencyObject)).DefaultValue)
        End Get
    End Property
End Class
person tolsen64    schedule 24.09.2013