-1

Hello this is my code:

public class Class1 : FrameworkElement
{
    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        var testOk = this.ActualWidth;
        var testNotOk = this.GetValue(ActualWidthProperty);
    }
}

TestNotOk is always zero, TestOk have right value. Why does this happen?

jaguar68
  • 159
  • 1
  • 1
  • 9
  • DPs are the backing store for the property itself. In this example, the Acutal Width is the CLR wrapper for the Class1.FrameworkElement.ActualWidth Property. However, the dp property that is declared is set to the null instance for Framework.ActualWidthProperty which should always be zero (numbers cannot ever be null). You may want to ask "Why do I want a DP in my class when I already have it?" – JWP May 26 '16 at 04:15
  • I need to store in 'currentDirection', because in my program this will change. When OnRender is called, sometime I'll use ActualWidth, sometime I need to use ActualHeight – jaguar68 May 26 '16 at 04:27
  • Is not a declaration of a custom dependency property. Try to read the code a bit more slowly ;-) If you prefer the code could be: public class Class1 : FrameworkElement { protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); var testOk = this.ActualWidth; var testNotOk = this.GetValue(FrameworkElement.ActualWidthProperty); } } testOk are right; testNotOk is always zero, that's the problem – jaguar68 May 26 '16 at 05:27
  • Now the code should be more clear – jaguar68 May 26 '16 at 05:45

2 Answers2

2

A look into the FrameworkElement source code reveals this:

public double ActualWidth
{
    get { return this.RenderSize.Width; }
}

After the first OnRender() call the ActualWidth property returns the same value as GetValue(ActualWidthProperty), at least in my test application.

Clemens
  • 123,504
  • 12
  • 155
  • 268
  • Unfortunatelly I need value of ActualWidth or other property, within OnRender, as shown in the code, not outside – jaguar68 May 26 '16 at 06:36
  • But you understand that this is the answer to your question, why `ActualWidth` and `GetValue(ActualWidthProperty)` return different values? – Clemens May 26 '16 at 06:39
  • I already knew this. If understood your test, you compare ActualWidth and GetValue(ActualWidthProperty) outside OnRender method override. I'm looking for a real solution to this problem. – jaguar68 May 26 '16 at 07:08
  • No, I'm doing this inside OnRender. Only on the first call GetValue returns 0. Later it's always the same as ActualWidth. – Clemens May 26 '16 at 07:13
  • And when you write "I already knew this". I honestly don't understand why you are asking the question this way. Why don't you directly ask "Why do `RenderSize.Width` and `GetValue(ActualWidthProperty)` not return the same value"? – Clemens May 26 '16 at 07:18
  • I don't get the same result: var testOk = this.ActualWidth; var testNotOk1 = this.GetValue(FrameworkElement.ActualWidthProperty); var testNotOk2 = this.GetValue(FrameworkElement.ActualWidthProperty); TestOk is great than zero; TestNotOk2 and TestNotOk1 are both zero. Calling GetValue(...) two times does'nt resolve the problem at all. – jaguar68 May 26 '16 at 08:06
  • I don't meant to call GetValue two times. I was talking about the second (and later) calls of OnRender. – Clemens May 26 '16 at 08:11
  • I can't wait for a second call, I need the value all the times, since the first call. – jaguar68 May 26 '16 at 08:21
0

A workaround can be:

typeof(Class1).GetProperty(ActualWidthProperty.Name).GetValue(this);
Clemens
  • 123,504
  • 12
  • 155
  • 268
jaguar68
  • 159
  • 1
  • 1
  • 9
  • Just to make sure you understand this correctly, it is equivalent to directly calling the `ActualWidth` property getter (expect that it's done by reflection), because it's identical to `typeof(Class1).GetProperty("ActualWidth").GetValue(this);`. It does not get the value of the `ActualWidthProperty` dependency property. – Clemens May 26 '16 at 08:56
  • I can't read ActualWidth directly because the property from which I need value is conditional in my program. Sometimes is ActualWidth, other times is ActualHeight, other time will be anything else. I don't know what kind of test you've done, but the solution with reflection works exactly as I expect. Hope now it is more clear what I've done. – jaguar68 May 26 '16 at 16:54
  • I didn't want to say that it won't work, just make sure you don't confuse things. You may however achieve what you want without reflection by a simple switch statement over all possible property names. – Clemens May 26 '16 at 17:08
  • Within OnRender I've to do minimum processing, and use of switch or other selection mechamism is not advisable. What you have initially misunderstood as "wrong custom property declaration", was exactly done for this purpose. The program know what property to use when object render based on that variable assigned externally. Although use of reflection is a workaround, it works Don't worry I'm not confusing things ;-) – jaguar68 May 26 '16 at 19:07
  • Be aware that reflection is less efficient than a simple switch. – Clemens May 26 '16 at 19:08