Почему свойство = null?

203
02 февраля 2019, 12:40

Я сделал свой UserConrol типа Button ModernBtn.xaml

<Button x:Class="ModernButton.ModernBTN"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:ModernButton"
         mc:Ignorable="d" 
         d:DesignHeight="100" d:DesignWidth="200" Name="myBtn" Background="Transparent">
<Button.Resources>
    <Style x:Key="default"></Style>
</Button.Resources>
<Button.Style>
    <Style TargetType="{x:Type Button}" BasedOn="{StaticResource default}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border Background="{Binding ElementName=myBtn, Path=ButtonColor}" CornerRadius="{Binding ElementName=myBtn, Path=CornerRadius}" Name="mainBorder">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"></RowDefinition>
                                <RowDefinition Height="Auto"></RowDefinition>
                            </Grid.RowDefinitions>
                            <TextBlock Text="{Binding ElementName=myBtn, Path=BtnText}" FontSize="25" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{Binding ElementName=myBtn, Path=ForeColor}"></TextBlock>
                            <Rectangle Fill="Lime" Height="5" VerticalAlignment="Bottom" Margin="0,0,0,20" Name="indicatorBtn" Width="0"></Rectangle>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Button.Style>

и часть ModerBtn.xaml.cs

public partial class ModernBTN : Button
{
    public Style ModernStyle
    {
        get { return (Style)GetValue(ModernStyleProperty); }
        set { SetValue(ModernStyleProperty, value); OnPropertyChanged("ModernStyle"); }
    }
    public static readonly DependencyProperty ModernStyleProperty = DependencyProperty.Register("ModernStyle", typeof(Style), typeof(ModernBTN));
    Color bgColor;
    Rectangle indicator;
    Border mainBorder;
    public ModernBTN()
    {           
        InitializeComponent();
        this.Resources["default"] = ModernStyle;
        this.Loaded += delegate (object sender, RoutedEventArgs e) {
            indicator = (Rectangle)this.myBtn.GetTemplateChild("indicatorBtn");
            mainBorder = (Border)this.myBtn.GetTemplateChild("mainBorder");
            bgColor = ((SolidColorBrush)mainBorder.Background).Color;
            MouseEnter += EnterAnim;
            MouseLeave += LeaveAnim;                            
        };
    }

почему ModernStyle = null; в строчке

this.Resources["default"] = ModernStyle;

хотя поидее я же указываю ModernStyle

<ModernButton:ModernBTN ButtonColor="Silver" CornerRadius="20" BGHover="Black" ForeColor="White">
        <ModernButton:ModernBTN.ModernStyle>
            <Style TargetType="{x:Type ModernButton:ModernBTN}">
                <Setter Property="BtnText" Value="Menu: "></Setter>
                <Setter Property="Foreground" Value="White"></Setter>
                <Setter Property="Width" Value="100"></Setter>
                <Setter Property="Height" Value="300"></Setter>
            </Style>
        </ModernButton:ModernBTN.ModernStyle>
    </ModernButton:ModernBTN>

Вообще идея в том чтоб я указывал стиль у кнопки и базовый стиль с ControlTemplate наследовался от стиля который я установил.

1) Как исправить ошибку чтоб все работало? 2) Если идеи как сделать проще?

Сорри за нытье но если можете чем то помочь то подскажите. Сижу уже 2 дня голову ломаю.

В вопросе который якобы дубликат была ошибка в том что стиль с ControlTemplate убирался скажем так. И кнопки считай и не было. Здесь ошибка в другом но я не знаю в чем.

Answer 1

Смотрите, myBtn — поле вашего класса ModernBTN. (Оно не видно вам, т. к. генерируется в partial-части класса, генерируемой из XAML-разметки.)

Инициализация этого поля происходит в конструкторе, внутри вызова InitializeComponent(). Поэтому до этого вызова myBtn всё ещё null.

Перенесите обращение к myBtn ниже, на строчку после InitializeComponent().

Ещё проще: внутри класса ModernBTN значение myBtn — это просто ваша кнопка, так что вы можете просто использовать вместо него this, его-то значение точно не будет равно null.

Answer 2

Окей, вопрос изменился, вот ответ к изменённому вопросу.

Смотрите, что означает

<ModernButton:ModernBTN ButtonColor="Silver" CornerRadius="20" BGHover="Black" ForeColor="White">
    <ModernButton:ModernBTN.ModernStyle>
        ...

Этот код находится вне класса ModernBTN, и выполняется следующим образом: вызывается конструктор ModernBTN, и после того, как он отработает, устанавливаются свойства наподобие ButtonColor или ModernStyle. (Сам код выполняется, очевидно, в контексте InitializeComponent() вашего окна.) Поэтому, понятно, во время пробега конструктора значение свойства равно null, ведь его ещё никто не установил.

Ваш подход неверен. Вы пытаетесь унаследоваться от динамически устанавливаемого стиля через code behind, и пытаетесь подгадать момент, в который свойства объектов будут установлены. Хотя этот подход можно «продавить», я бы крайне не рекомендовал этот путь, проблемы будут встречаться на каждом шагу.

Сделайте стиль default статическим, и положите его в App.xaml, а не пытайтесь установить его динамически. Будет намного проще.

READ ALSO
Как сделать переменную членом класса?

Как сделать переменную членом класса?

Как сделать переменную cheked членом класса timer ?

177
Добавление записей в таблицу Access при помощи C#

Добавление записей в таблицу Access при помощи C#

В моем проекте имеется кнопка "Добавить запись в Access"После того, как я записал все необходимые для добавления данные, я нажимаю на кнопку

254
Список стандартных приложений Windows

Список стандартных приложений Windows

Как можно получить список стандартных приложений Windows и занести их в comboBox и запускать, нажав на Button? Возможно,есть какие-то варианты, не прописывая...

178