3

In a WPF application and using the Fluent Ribbon Control Suite, I have a DropDownButton that opens up a Gallery that lets the user select a color.

Exibit 1

Here is the XAML that creates the button:

<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>

The SelectedItem of the Gallery returns the Name of the color. I want to make the Icon of the button display the actual color that was selected. Can this be done purely with XAML? I have been trying various things found online but so far have been unable to get anything other than the color name to appear where I want the color rectangle to go. Look for the "What Goes Here?" in the XAML above.

I appreciate any helpful suggestions. Thanks for reading!

UPDATE:

I tried the answer given below and it still doesn't work. I must have something wrong. Here's an updated listing of all the XAML code for this button. Take a look at the XAML for the Gallery itself and the binding for the SolidColorBrush and tell me if you see what i've done wrong.

<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>
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
tolsen64
  • 881
  • 1
  • 9
  • 22

2 Answers2

3

On the page 17 of the walkthrough you have an example of what you are trying to achieve.

You can download it here : http://fluent.codeplex.com/documentation

Taken from the walkthrough :

enter image description here

<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>

UPDATE

I see nothing wrong in your code, I've pasted it and it ran successfully, here is it again pasted from my working test.

<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>
aybe
  • 15,516
  • 9
  • 57
  • 105
  • Thanks. I tried that. It works if I use the ColorGallery but I want to use my own Gallery that displays all the System.Windows.Media.Color's. This is my XAML for the Brush, but it doesn't change the color of the button's icon: . When I MessageBox galCommentColor.SelectedValue.ToString, I get the color name (DeepPink for example). – tolsen64 Sep 23 '13 at 15:38
  • Updated my answer, your code works fine for me. Not sure what to advise, do you have the latest Fluent package version from Nuget ? – aybe Sep 23 '13 at 18:17
  • I'm using the pre-release version 2.1.0. I'll try the stable version and see if that makes a difference. Thanks for helping me keep my sanity :) I got it to work using the button's DropDownClosed event and setting the icon color in code... but I want to keep it all XAML if I can. Thanks again. Marking as accepted answer. – tolsen64 Sep 23 '13 at 20:25
  • One thing to note. I created a converter and added the converter property to the SolidColorBrush element: Converter={StaticResource ColorNameToSolidColorBrushConverter}. I added Debug.WriteLine to the converter code and I don't see anything written to Debug when I select a color. So i'm not even sure it's firing on the selection change. – tolsen64 Sep 23 '13 at 20:35
  • Definitely you should be able to use XAML only, unless you need a converter. If you want, upload a (small) zipped project with your issue somewhere and post the link, I will take look at it. – aybe Sep 23 '13 at 21:46
  • [Here's the link](https://www.dropbox.com/s/6fysssi6ipufvw5/CodeEditor.zip?m) I didn't include all the icons for the other buttons. I'm only concerned about the one button on the Colors tab. Thanks for looking. – tolsen64 Sep 24 '13 at 15:18
  • I took me only a few minutes to find the cause, almost an hour to try but fail to fix it ... From what I've seen the problem lies in the Popup of the color DropDownButton, the binding cannot be solved as popups are detached from the visual tree. But here are two solutions for you : move the color group to first tab, it works there. Second solution : search about binding with popups / ask a question at fluent web site (probably easier/better). Try to look at their samples, too. – aybe Sep 24 '13 at 16:54
  • I made another test, LargeIcon seems buggy because with Icon it does work. On your code try to replace DropDownButton.LargeIcon with Icon then set DropDownButton.SizeDefinition="Middle" you'll see that it works (with the code you sent). File a bug at their website ! – aybe Sep 24 '13 at 18:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/37969/discussion-between-tolsen64-and-aybe) – tolsen64 Sep 24 '13 at 19:14
0

Thanks to Aybe for confirming that it's not me. I did get the result I wanted by using a converter on the LargeIcon property of the DropDownButton.

Here's the 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>

And the code:

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
tolsen64
  • 881
  • 1
  • 9
  • 22