views:

94

answers:

4

Well i have a control that inherits usercontrol(view) and im using it as you use a usercontrol (a base control) now here is the problem if i do

MessageBox.Show(this.GetType().ToString());

i get different messages in runtime and design time, in design time i get View and i runtime i get the class name of the xaml file inheriting the view...

How can i get the inheriting class type in design time instead of the base class?

Here comes some code:

First we have the view Class

public class View : UserControl
{
    public override void OnApplyTemplate()
    {
        MessageBox.Show(this.GetType().ToString());
        base.OnApplyTemplate();
    }
}

Then we have a XAML file:

<local:View x:Class="WpfApplication2.Test"
             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:WpfApplication2"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>

    </Grid>
</local:View>

now if you compile and open "WpfApplication2.Test" in VisualStudio 2010 you will get a message box that says "WpfApplication2.View"..

But if you place the Test control in your MainWindow and press Run(F5) you get WpfApplication2.Test.. what i want is to have the same response in design time that i have in run time...

A: 

Im still learning WPF so this probably isn't what you are looking for.

In design time and runtime, this.GetType().ToString(); returns to me "WpfApplication2.View" in the message box.

So view is being returned in both modes. I will state I have made one slight change to your code.

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for View.xaml
    /// </summary>
    public partial class View : UserControl
    {
        public override void OnApplyTemplate()
        {
            MessageBox.Show(this.GetType().ToString());
            base.OnApplyTemplate();
        }
    }
}

I have it marked as a partial class instead of just class, as the XAML is obviously split out from the .cs file. I would not think this would be the problem though.

JonWillis
that would not work sorry...
Petoj
In his question, class 'View' was the base class of class 'Test'. Class 'Test' was the partial class defined in the code-behind of Test.xaml.
Mike Schenk
No problems, worth a shot though. I remember the problems with DesignMode property with VisualStudio been somewhat useless when nesting views.@Mike Schenk, thanks for clearing that up. In rereading the code that did confuse me not seeing test inherit from view.
JonWillis
Edit: Partial does only work on one class (you cant have one class thats partial to many classes) and partial is only within the same assembly...
Petoj
+2  A: 

Well, the problem is that the XAML designer in Visual Studio 2010 does not instantiate the actual class declared in the code-behind. Instead, it only instantiates its base class.

If you think about it, as you modify your XAML, you are actually modifying the very class declared in the code-behind since it is a partial class combined with another part created from the XAML. So the designer can't create an instance of your class: it's still being created.

I don't think you're going to be able to accomplish what you're after without writing code that somehow interacts with Visual Studio itself to ask what file is actually being designed.

You can at least guard your code using a check for DesignerProperties.GetIsInDesignMode().

See these links for some related information:

Troubleshooting WPF Designer load failures

What gets called when the VS 2008 XAML Designer view tries to render the GUI?

Don't do that in the WPF Designer (Cider)!

Mike Schenk
A: 

The VS2010 Designer (Cider) is instantiating an instance of the base class when you design a derived control. There's nothing you can do about it.

Omer Mor
well i don't wanna change what cider does i just want to know the type or the name of the type, this does not have to be done by GetType, it could be any other method or property..
Petoj
+1  A: 

Petoj, I think you should ask yourself / describe why you want to know the name of the type and why it's causing troubles when it differs on design time. Unless you're fighting windmills and won't get a reasonable answer in my opinion.

Update — pseudocode of a simple workaround:

if (IsDesignTime)
   use this.GetType()
else
   use this.GetType().BaseType

Update 2: On design-time, there is no way to get the name of the descendant class being designed. The problem should be probably solved in a different way, not depending on the name of the actual class.

Ondrej Tucny
Well i have a list of Views and ViewModels (or their types) now when im in design time i want to set the DataContext to the right type of viewmodel but to be able to do that i need the type so i can compare the types.
Petoj
@Petoj Updated my answer with a reasonable (IMHO) workaround.
Ondrej Tucny
Sure that would give the same result but its not the result that i need...
Petoj
@Petoj Read your question once again. Now I understand: you want the name of the **descendant** class. As Omer Mor pointed out in his answer, **there's probably no way to get it** — the fact is the visual designers across Microsoft's technologies do instantiate the _base_ class, not the descendant class being actually designed. So, in your case, it might be faster to solve the problem you are trying to solve by knowing the name of the type in a completely different way.
Ondrej Tucny