Search code examples
wpfcolorscomboboxlocalizationcolor-picker

WPF localizabled color picker combobox


i want to localize the colors of a combobox colorpicker.

I know, that i had to translate the color names manually.

Think you need to know, how i fill my combobox and display the data.

here is my xaml for the combobox together with the itemtemplate:

<ComboBox x:Name="cmbxFarbeKategorie" Margin="5,0,0,0" Height="40" FontSize="18"
     SelectionChanged="cmbxFarbeKategorie_SelectionChanged">
<ComboBox.ItemTemplate>
      <DataTemplate>
           <DockPanel LastChildFill="False" Margin="0,0,10,0">
               <Rectangle VerticalAlignment="Center" Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
               <TextBlock x:Name="tbDataTempcmbx"  VerticalAlignment="Center" Tag="{Binding Name}" Text="{Binding Name}" />
           </DockPanel>
      </DataTemplate>
</ComboBox.ItemTemplate>

and at runtime i fill it once with the default definded color names from .net:

foreach (var col in typeof(Colors).GetProperties())
{
      cmbxFarbeKategorie.Items.Add(col);
}

Now i need a way to access to the VisualTree of each item and replace the Binding of the text with the translated color.

Translation method (used this one) gives back a string.

I don't want to rename the color, i only want to replace the displayed text.

My problem is, that i know how to access to the TextBlock at the ItemTemplate, but after trying this, i found out, that this is not the right way.

I think, i had to access for each item at my combobox to the visual childs and change there the text of the textblock to the translated version.

But don't found out how - or is there maybe a easier way?


Solution

  • After trying a lot of things i found a solution yesterday morning.
    It would be better not to store only the color.

    The default color doesn't includes other thinks than a name and a value.
    Therefore i wrote a own class for adding these colors to the combobox. Ended in creating a string for Tag, one for Name and a Color.

    Name and Color aren't updated if i want to localize the names.
    The Tag-Property is only used to store the localized names somewhere and can bind my Text-Property to another value than the english default name (which is stored at the Name-Property).

    I want not to update the name property because this would be ending at converting many times at both directions and this is not a good way.

    Step 1 - Create a own Class to store the color:

     public class ColorItem
    {
        public string Tag
        {
            get;
            set;
        }
    
        public string Name
        {
            get;
            set;
        }
    
        public Color Color
        {
            get;
            set;
        }
    }
    

    Second step was to update my foreach-loop:

    if the system language is not english (i check this once at the start of the application and store it), than i update the Tag-Property of the item with the translated name.

    foreach (var col in typeof(Colors).GetProperties())
    {
         string strColor = col.ToString().Replace("System.Windows.Media.Color ", "");
             string strTag = "";
             switch (iSystemLanguage)
             {
             case 0:
                 strTag = strColor;
                 break;
            case 1:
                 drawg.Color drawingcolor = drawg.Color.FromName(strColor);
                 strTag = GetGerManColorNames.GetGermanName(drawingcolor);
                 break;
            default:
                 strTag = strColor;
                 break;
           }
           cmbxFarbeKategorie.Items.Add(new ColorItem() { Name = strColor, Tag = 
                    strTag, Color = (Color)ColorConverter.ConvertFromString(strColor) });
        }
    

    At last step i had to update my bindings at my ComboBox:

    <ComboBox x:Name="cmbxFarbeKategorie" Margin="5,0,0,0" Height="40" FontSize="18"
     SelectionChanged="cmbxFarbeKategorie_SelectionChanged">
    <ComboBox.ItemTemplate>
          <DataTemplate>
               <DockPanel LastChildFill="False" Margin="0,0,10,0">
                   <Rectangle VerticalAlignment="Center" Fill="{Binding Name}" 
                                   Width="16" Height="16" Margin="0,2,5,2" />
                   <TextBlock x:Name="tbDataTempcmbx"  VerticalAlignment="Center" 
                                     Tag="{Binding Name}" Text="{Binding Tag}" />
               </DockPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
     </ComboBox>
    

    It's a little bit more work to get the SelectedItem (for example:at SelectionChanged), but i think it's a good way to localize the color and store the right english name for using at the application.