kurchavy
kurchavy

Reputation: 37

UserControl's constructor

I have my own WPF UserControl (e.g. Image + ViewBox - it does not matter). This control has boolean Dependency property, e.g. NeedToDrawRect. What I want to achieve: when user sets (in XAML) this property to true, I need to perform some action - but only once. I've planned to perform this action in c-tor, but it seems that I can not see this property value on that stage yet:

XAML:

<pzi:PanZoomImage Grid.Row="1" Grid.Column="0" NeedToDrawRect="True" />

UserControl constructor:

public PanZoomImage()
{
    InitializeComponent();

    LayoutRoot.DataContext = this;

    // Here NeedToDrawRect is still false
    if (NeedToDrawRect)
           DoSmth();            
}

So, where can I check value that user set in XAML. Of course I can override OnRender and check there every time, but I'd like to use the right way to do this.

Upvotes: 1

Views: 211

Answers (2)

undefined
undefined

Reputation: 142

You can use PropertyChangedCallback while creating the dependency property. If you want it to be executed ONLY ONCE and then do not allow the user to change it, you can try manipulating it in the PropertyChangedCallback.

    public bool NeedToDrawRect
    {
        get { return (bool)GetValue(NeedToDrawRectProperty); }
        set
        {
            SetValue(NeedToDrawRectProperty, value);
        }
    }


    public static readonly DependencyProperty NeedToDrawRectProperty =
        DependencyProperty.Register("NeedToDrawRect",
            typeof(bool),
            typeof(PanZoomImage),
            new PropertyMetadata(false, OnNeedToDrawRectChanged ));

    private static void OnNeedToDrawRectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = d as PanZoomImage;
        if (control!=null && (bool)e.NewValue == false && (bool)e.OldValue == true)
        {
            control.NeedToDrawRect = true; // user won't be able to set it to false again.
        }
    }

This should work. If you are using a checkbox to perform the operation, Bind the IsReadOnly property of the checkbox to the property NeedToDrawRect so that once the user sets it to true, the user won't be able to change it again. You might need an InverseBooleanConverter to do this.

Upvotes: -1

mm8
mm8

Reputation: 169400

Register a PropertyChangedCallback for the dependency property:

public static readonly DependencyProperty NeedToDrawRectProperty = DependencyProperty.Register(nameof(NeedToDrawRect),
    typeof(bool), typeof(PanZoomImage ), new PropertyMetadata(new PropertyChangedCallback(OnValueChanged)));

public bool NeedToDrawRect
{
    get { return (bool)GetValue(NeedToDrawRectProperty); }
    set { SetValue(NeedToDrawRectProperty, value); }
}

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var ctrl = (PanZoomImage)d;
    var newValue = (bool)e.NewValue;
    //...
}

The callback will be invoked whenever the dependency property is set to a new value.

If you only want to do something once, you could use a private field to keep track of whether the callback has been invoked before, e.g.:

private int n;

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (n++ > 0)
    {
        var ctrl = (PanZoomImage)d;
        var newValue = (bool)e.NewValue;
        //...
    }
}

Upvotes: 4

Related Questions