Variable of Component is null in WPF

I have next code:

struct CalculatorWallInput

WallView(UserControll)
part of XAML

...
<TextBox x:Name="nameTB" TextChanged="nameTB_TextChanged"/>
<controls3:NumericUpDown x:Name="DistanceNUD" ValueChanged="DistanceNUD_ValueChanged"/>
<CheckBox x:Name="IsHasDoorCB" Checked="IsHasDoor_Checked"/>
<CheckBox x:Name="IsHasWindowCB" Checked="IsHasWindow_Checked"/>
...

and in cs I’m declare my DependencyProperty

public CalculatorWallInput Wall
{
    get { return (CalculatorWallInput)GetValue(WallProperty); }
    set { SetValue(WallProperty, value); }
}
public static readonly DependencyProperty WallProperty =
    DependencyProperty.Register("Wall", typeof(CalculatorWallInput), typeof(WallView), new PropertyMetadata(new CalculatorWallInput(), WallChanged));
private static void WallChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if(d is WallView wv && e.OldValue != e.NewValue)
    {
        try
        {
            CalculatorWallInput newVal = ((CalculatorWallInput)e.NewValue);
            wv.exp.Header = "Стена: " + newVal.Name;
            wv.nameTB.Text = newVal.Name;
            wv.IsHasDoorCB.IsChecked = newVal.IsHasDoor;
            wv.IsHasWindowCB.IsChecked = newVal.IsHasWindow;
            wv.WindowHeightNUD.Value = (double)newVal.WindowHeight;
            wv.WindowWidthNUD.Value = (double)newVal.WindowWidth;
            wv.LayersCB.SelectedIndex = (int)newVal.MaterialsCount;
            wv.Mat1CB.SelectedIndex = (int)newVal.Material1;
            wv.Mat2CB.SelectedIndex = (int)newVal.Material2;
            wv.Mat1ThNUD.Value = (double)newVal.Thickness1;
            wv.Mat2ThNUD.Value = (double)newVal.Thickness2;
            wv.WallPlaseCB.SelectedIndex = (int)(newVal.WallPlase);
        }
        catch (Exception)
        {

        }
    }
}

and in MainWindow

<ItemsControl x:Name="tStack">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <controls:WallView Wall="{Binding}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

So, when I run this app, I encounter a Null Reference Exception on ‘wv.<<random component>>’ in WallChanged method.

From what I understand, in WPF, my property is being set before my component is initialized. As a result, some components are already not null, while others remain null.

I tried to add Task.Delay in the WallChanged method and make it async (I thought it would wait while the component is initialized). I already tried using a ‘while’ loop, but I keep getting exceptions (I know this solution is too naive for waiting for initialization). Nothing is helping.

Is there a way to address this issue, or should I create a ViewModel based on my structure?

  • 1

    my property is being set before my component is initialized” – this is actually not possiblle when there is the mandatory InitializeComponent() call as first statement in the WallView constructor.

    – 

  • I’m short on time so I can’t write a full example but e.NewValue can be null. The property changed event will fire even if the value assigned is null and as the application starts up, that’s a real possibility. You aren’t checking to see if it’s null before using it.

    – 

  • This could be related to initialization – given that all wv. references are child elements of WallView. What you are doing is generally a code smell, that obviously lead to this situation. You must not reference the elements explicitly. At least if you do, ensure WallView was properly initialized before. The correct way to handle child elements is via data binding. You must implement dependency properties and bind the child elements to them. Then only modify these properties. This takes the responsibility from you and gives the framework the chance to initialize the child elements correctly.

    – 




  • 1

    I would suggest you remove that handler out the view entirely. Put the logic in model or viewmodel instead. Bind those values in the view. Not sure if bionicode is saying that. Even if some of those things would require new dependency properties or attached dependency properties you will then avoid a slew of nasty issues.

    – 




Leave a Comment