[WPF] Enum Tooltip Binding

ํ˜„์žฌ Enum์„ ObjectDataProvider๋ฅผ ํ†ตํ•ด์„œ Combobox์— Item ์œผ๋กœ Binding ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด Item๋“ค์— ๋Œ€ํ•ด Tooltip์„ ๋งŒ๋“ค์–ด์„œ ์„ค๋ช…์„ ๋„์šฐ๊ณ  ์‹ถ์€๋ฐ, ์ด๋Ÿฐ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ์š”?

์ข‹์•„์š” 1

@Vincent ํ˜น์‹œ ์กฐ๊ธˆ ๋” ์„ค๋ช…ํ•ด์ฃผ์‹ค ์ˆ˜ ์žˆ์œผ์‹ ๊ฐ€์š”! :smile:

์ข‹์•„์š” 1
<ObjectDataProvider x:Key="EPlatform"
                    MethodName="GetValues"
                    ObjectType="{x:Type clr:Enum}">
    <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="awesomeswagenum:ETargetSite"/>
    </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
...
<dxe:ComboBoxEdit Grid.Column="1"
                  x:Name="DxCmbSelectPlatform"
                  ItemsSource="{Binding Source={StaticResource EShopCode}}"
                  SelectedItem="{Binding ShopCategoryKind}"
                  IsTextEditable="False"
                  VerticalContentAlignment="Center"
                  HorizontalContentAlignment="Center"
                  FontFamily="{StaticResource MainFont}"
                  FontSize="17">
    <dxe:ComboBoxEdit.StyleSettings>
        <dxe:ComboBoxStyleSettings/>
    </dxe:ComboBoxEdit.StyleSettings>
</dxe:ComboBoxEdit>

์‹ค๋ฌด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์‹ค์ œ XAML์ธ๋ฐ ์ด๋Ÿฐ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ Enum๊ฐ’์ด View์— ๋ณด์ด๊ฒŒ ๋˜๋‹ˆ๊นŒ ์„ค๋ช…์ด ์—†์–ด์„œ Tooltip์„ ์‚ฌ์šฉํ•ด๋ณผ๊นŒํ•˜๋Š”๋ฐ, ์ด ๊ฒฝ์šฐ ์–ด๋–ค์‹์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผํ•˜๋Š” ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ข‹์•„์š” 1

@Vincent DevExpress ์„ค์น˜์ค‘์ž…๋‹ˆ๋‹ค. :smile:
์ด๋”ฐ ํ•œ๋ฒˆ ํ™•์ธํ•ด๋ณผ๊ฒŒ์š”~

์ข‹์•„์š” 1

์™€์šฐ ใ„ทใ„ท ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!!! ์‚ฌ์‹ค ๋ฐ๋ธŒ์งˆ๋ฌธ์œผ๋กœ ๋ถ„๋ฅ˜๋˜๋ฉด ๋ฐ๋ธŒ์ต์Šคํ”„๋ ˆ์Šค์— ์งˆ๋ฌธ๋‚จ๊ธฐ๋Š”๊ฒŒ ๋งž๋Š”๋ฐ ใ…Žใ…Žโ€ฆ; ๊ทธ๋ƒฅ WPF ๋ฐฉ์‹์œผ๋กœ ํ•ด์ฃผ์…”๋„ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค!

์ข‹์•„์š” 1

@Vincent ํ•˜์‹œ๋ ค๋Š”๊ฒŒ ์ด๊ฒŒ ๋งž์„์ง€ ๋ชจ๋ฅด๊ฒ ๋„ค์š”โ€ฆ :disappointed_relieved:

<Window>
    <Window.Resources>
        <ObjectDataProvider x:Key="ODP"
                    MethodName="GetValues"
                    ObjectType="{x:Type s:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:Marvel"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

        <Style TargetType="{x:Type dxe:ComboBoxEditItem}" x:Key="CMBI">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" 
                                   ToolTip="{Binding}"
                                   Foreground="Red" />
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <dxe:ComboBoxEdit HorizontalAlignment="Left" 
                          VerticalAlignment="Top" Width="150" 
                          ItemsSource="{Binding Source={StaticResource ODP}}"
                          ItemContainerStyle="{StaticResource CMBI}"/>
    </Grid>
</Window>
์ข‹์•„์š” 2

๋„ค ์ด๊ฑฐ๋ž‘ ๋น„์Šทํ•œ๋ฐ Tooltip์— ์ œ๊ฐ€ ๋ฐ”์ธ๋”ฉํ•˜๋Š” Enum์— ๊ด€ํ•œ ์„ค๋ช…์ด ๋ถ€์กฑํ–ˆ๋„ค์š” ใ…Žใ…Ž;;

    public enum ERegistState
    {
        /// <summary>
        /// ์ƒํ’ˆ์„ ๋ง‰ ํฌ๋กค๋ง ํ•ด์™”์„ ๋•Œ ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ
        /// </summary>
        [Display(Name = "Init", Description = "์ƒํ’ˆ์„ ํด๋กค๋งํ•œ ์งํ›„์˜ ๋ฐ์ดํ„ฐ")]
        Init,

        [Display(Name = "Hold", Description = " ๋ณด๋ฅ˜ ์ƒํ’ˆ")]
        Hold,

        [Display(Name = "ImgHold", Description = "์ด๋ฏธ์ง€ ์ž‘์—… ๋ถˆ๊ฐ€์˜ ์ด์œ ๋กœ ๋ณด๋ฅ˜๋œ ์ƒํ’ˆ")]
        ImgHold,

        /// <summary>
        /// ๋“ฑ๋ก๋˜์ง€ ์•Š์€ ์ƒํ’ˆ ์ค‘์—์„œ ์ˆ˜์ • ์ค‘์ธ ๊ฒƒ. (๋“ฑ๋กํ•˜๋‹ค๊ฐ€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ๋„ Edit์ด๋ฉฐ ๋“ฑ๋ก ์‹œ Error Message๋กœ ๊ตฌ๋ถ„ํ•จ.)
        /// </summary>
        [Display(Name = "Edit", Description = "๋ณด์ • ์ž‘์—… ์ง„ํ–‰์ค‘์ธ ์ƒํ’ˆ")]
        Edit,
        /// <summary>
        /// ์ •์ƒ ๋“ฑ๋ก์™„๋ฃŒ
        /// </summary>
        [Display(Name = "Regist", Description = "์ƒํ’ˆ์ด ์‡ผํ”ผ์— ๋“ฑ๋ก๋œ ์ƒํƒœ")]
        Regist,

        /// <summary>
        /// ํ‹ฐ์–ด ์„ธํŒ… ์™„๋ฃŒ
        /// </summary>
        [Display(Name = "Tier", Description = "์ƒํ’ˆ์ด ์‡ผํ”ผ์— ๋“ฑ๋ก๋œ ์ดํ›„ 2Tier์ฒ˜๋ฆฌ๊นŒ์ง€ ๋œ ์ƒํƒœ")]
        Tier,

        /// <summary>
        /// ํ• ์ธ ์ ์šฉ ์™„๋ฃŒ
        /// </summary>
        [Display(Name = "Discounted", Description = "์ƒํ’ˆ์ด ์‡ผํ”ผ์— ๋“ฑ๋ก๋œ ์ดํ›„ Discount ๊นŒ์ง€ ์ ์šฉ๋œ ์ƒํƒœ")]
        Discounted
    }

์š”๋Ÿฐ์‹์ผ ๋•Œ ์—ฌ๊ธฐ์„œ Display ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ XAML๋กœ ๋ฐ”์ธ๋”ฉํ•ด์„œ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์˜ˆ์ œ๋กœ ์ฃผ์‹  ๊ฒƒ์ฒ˜๋Ÿผ ํ•˜๋ฉด Tooltip์— enum๊ฐ’์ด ์ฐํ˜€๋‚˜์™€์„œ์š” ใ…Žใ…Ž;;
ํ˜ผ์„ ๋“œ๋ ค ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.

์ข‹์•„์š” 1

ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค~
์•Œ๋ ค์ฃผ์‹  ์Šคํƒ€์ผ์— Tooltip์— Converter๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
๋„์™€์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

<dxe:ComboBoxEdit.ItemContainerStyle>
    <Style TargetType="{x:Type dxe:ComboBoxEditItem}">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <TextBlock Text="{Binding}" 
                               ToolTip="{Binding Converter={StaticResource EnumDisplayConverter}}"/>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</dxe:ComboBoxEdit.ItemContainerStyle>
    public class EnumDisplayConverter :  IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ERegistState enumValue = (ERegistState)Enum.Parse(typeof(ERegistState), value.ToString());
            
            return AttributeHelper.GetAttribute<DisplayAttribute>(enumValue).Description;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }

AttributeHelper.GetAttribute() ๋ฉ”์„œ๋“œ๋Š” ๊ตฌ๊ธ€๋งํ•ด์„œ ์ฐพ์•„๋‚ธ ํ•ด๋‹น Enum์— ๋Œ€ํ•œ DisplayAttribute๋ฅผ ์ฐพ์•„๋‚ด๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

์ข‹์•„์š” 3

ํ˜น์‹œ ์ปจ๋ฒ„ํ„ฐ์— MarkupExtension์„ ์ƒ์†๋ฐ›์œผ๋ฉด ์–ด๋–ค ์ด์ ์ด ์žˆ๋‚˜์š”?

์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ๋Š” ์ฒ˜์Œ์ด๋ผ ์–ด๋–ค ์ด์ ์ด ์žˆ๋Š”์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค :thinking:

์ข‹์•„์š” 1

์—Œใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค ์•„๋ฌด ์ด์  ์—†์Šต๋‹ˆ๋‹ค. ์‚ญ์ œํ• ๊ฒŒ์š” ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹์ด๊ฑฐ์ €๊ฑฐ ํ•ด๋ณด๋‹ค๊ฐ€ ์•ˆ์ง€์› ๋„ค์š” ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹

์ข‹์•„์š” 1

์ฒ˜๋ฆฌํ•˜์‹  ๋ฐฉ๋ฒ•๊ณผ ๋น„์Šทํ•˜๊ฒŒ

TypeConverter ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•ด ๋ณด์‹œ๋Š” ๊ฒƒ๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
TypeConverter๋Š” ๋ฐ”์ธ๋”ฉ ๋Œ€์ƒ์ด View์— ํ‘œ์‹œ ๋ ๋•Œ ์ž๋™์œผ๋กœ ์ฐธ์กฐ๋˜์„œ ์ปจ๋ฒ„ํ„ฐ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜์–ด
xaml์ƒ์— ๋ช…์‹œ์ ์œผ๋กœ Binding Converter ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค.:slight_smile:

์ข‹์•„์š” 3

@aroooong ์ข‹์€ ๋ฐฉ๋ฒ•์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค!! :smile:

๊ฐ„๋‹จํ•˜๊ฒŒ ์ƒ˜ํ”Œ ๋ถ€ํƒ๋“œ๋ ค๋„ ๋ ๊นŒ์š”?

์ข‹์•„์š” 1

์ฝ”๋“œ๋Š” ์ƒ์ค€๋‹˜ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ์ธ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

[TypeConverter(typeof(EnumDisplayConverter <ESecuritiesCompanyType>))]
public enum ERegistState
{
        [Description("์ƒํ’ˆ์„ ํด๋กค๋งํ•œ ์งํ›„์˜ ๋ฐ์ดํ„ฐ")]
        Init,
        [Description("๋ณด๋ฅ˜ ์ƒํ’ˆ")]
        Hold,
        [Description("์ด๋ฏธ์ง€ ์ž‘์—… ๋ถˆ๊ฐ€์˜ ์ด์œ ๋กœ ๋ณด๋ฅ˜๋œ ์ƒํ’ˆ")]
        ImgHold,
}

public class EnumDescriptionConverter<T> : EnumConverter
{
     public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        TODO .. ๋ฆฌํ”Œ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด์„œ Description์–ดํŠธ๋ฆฌ๋ทฐํŠธ ๊ฐ’ ํŒŒ์‹ฑ
    }
}

ERegistState์ด ๋ฐ”์ธ๋”ฉ ์ฒ˜๋ฆฌ๋œ View๊ฐ€ ํ™”๋ฉด์— ํ‘œ์‹œ๋  ๋•Œ
TypeConverter ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•ด์„œ EnumDescriptionConverter๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
View์— ํ‘œ์‹œ๋˜๋Š” ๋‚ด์šฉ์€ ConvertTo๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ๋กœ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ข‹์•„์š” 4

์˜คํ˜ธ!! ์ด๊ฒƒ๋„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค ใ…Žใ…Ž ๊น€์‚ฌํ•ฉ๋‹ˆ๋‹ค!!

์ข‹์•„์š” 1