Весёлая кнопыська AwesomeButton :)
От: Baiker  
Дата: 29.06.23 21:41
Оценка: 4 (1)
Очень люблю, когда на кнопках есть цветные иконки, позволяющие мгновенно понимать назначение (это у меня ещё со времён Delphi повелось).
Но т.к. гемороиться с картинками неохота, использую бесплатный Awesome Font (версии 5).
Соотв. кнопка состоит из TextBlock для иконки и TextBlock для текста. Самые часто нужные проперти вынул на верхний уровень.
Получился вот такой говнокодик:

  Незамутнённый C# код
public class AwesomeButton : Button
{
    public TextBlock txtCaption;
    public TextBlock txtIcon;
    
    public AwesomeButton ()
    {
        #region create Button content manually
        txtCaption = new TextBlock {
            VerticalAlignment = VerticalAlignment.Center,
            HorizontalAlignment = HorizontalAlignment.Center,
        };
        txtIcon = new TextBlock {
            Text = "\uF005",// star
            FontFamily = new FontFamily("Font Awesome 5 Free Regular"),
            FontSize = 16,
            Padding = new Thickness(5, 2, 5, 2),
            VerticalAlignment = VerticalAlignment.Center,
            HorizontalAlignment = HorizontalAlignment.Center, 
        };
        txtIcon.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Ideal);
        
        var dock = new DockPanel();
        DockPanel.SetDock(txtIcon, IconPos);
        dock.Children.Add(txtIcon);
        dock.Children.Add(txtCaption);
        
        var grid = new Grid();// needed only to be sure 'dock' is shrinked to all avl space
        grid.Children.Add(dock);
        this.Content = grid;
        #endregion
    }
    
    /// <summary>String of characters from 'Awesome' font</summary>
    public string IconText
    {
        get => txtIcon.Text;
        set => txtIcon.Text = value;
    }

    Dock _iconPos = Dock.Left;
    public Dock IconPos
    {
        get => _iconPos;
        set {
            _iconPos = value;
            DockPanel.SetDock(txtIcon, _iconPos);
        }
    }
    
    public Brush IconColor
    {
        get => txtIcon.Foreground;
        set => txtIcon.Foreground = value;
    }
    
    public double IconSize
    {
        get => txtIcon.FontSize;
        set => txtIcon.FontSize = value;
    }
    
    /// <summary>Text appearing on the button</summary>
    public string Text
    {
        get => txtCaption.Text;
        set => txtCaption.Text = value;
    }
    
    public new bool IsEnabled
    {
        get => base.IsEnabled;
        set {
            base.IsEnabled = value;
            txtIcon.Opacity = (value ? 1.0 : 0.5);// icon is not affected by IsEnabled - make disabled look manually
        }
    }
}


Если выставлять IconPos, можно регулировать, где иконка появится — на всех 4 сторонах света. Обратите внимание ещё на txtCaption и txtIcon — это как раз "выставленные наружу" наши текстбоксы, позволяющие в коде
регулировать то, что не видно в WPF. К слову, почему-то нельзя написать в XAML

 <AwesomeButton txtCaption.FontSize="100" />


Если подскажете ПОЧЕМУ, буду очень рад. (сейчас это поля, но даже когда они были пропертями, всё равно XAML не позволял такой финт) Ну а работающий вариант такой:

<cmn:AwesomeButton IconPos="Left" Click="btnRefresh_Click" Text="Refresh" IconText="" IconSize="18" IconColor="DodgerBlue" Padding="3" />


Да, ещё вопрос: нужно ли к этому классу писать что-то вроде

static AwesomeButton()
{ 
    DefaultStyleKeyProperty.OverrideMetadata(typeof(AwesomeButton), new FrameworkPropertyMetadata(typeof(AwesomeButton))); 
}


Или WPF'у достаточно того, что класс и так напрямую унаследован он Button?

Публикую затем, что в WPF такого нет и не будет — может кому пригодится, чтобы самим не гемороиться. Ну и цель №2 — критика.
Прежде, чем вы закидаете говном мою кнопыську, сразу напишу в оправдание: я не особый спец по WPF, юзаю в осн. готовые контролы, а процесс создания кнопки с нуля — это полный мрак! (спасибо MS)
Соотв. я решил задачу максимально простым методом — тупо унаследовал класс и добавил пропертей. Это я к тому, что этот путь тоже оправдан — люди, которые не особо углублялись в WPF, вполне смогут улучшать мой код.
Короче, прошу не столько возгласов "да тут шаблоны надо было на 3 километра написать!", сколько рациональных улучшений именно для моего варианта контрола. Понятно, что кое-что нахардкодил, но это невелик грех, интересны остальные аспекты.
Всем заранее спасибо!
Отредактировано 29.06.2023 22:03 Baiker . Предыдущая версия . Еще …
Отредактировано 29.06.2023 22:02 Baiker . Предыдущая версия .
Отредактировано 29.06.2023 21:58 Baiker . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.