3

I am using WPF and I'm trying to make a class inherit from UserControl and use that class as a base class for other classes. I've read numerous articles on how to do this (such as this one which has over 50 upvotes), but they all say the same thing and none of them work.

I have this code:

namespace MyNamespace {
    // handwritten
    public class BaseControl : UserControl { }

    // generated by the IDE
    public partial class XAMLControl1 : UserControl {
        ...
    }
}

Now, I change that line to

public partial class XAMLControl1 : BaseControl {

And in the XAML, I change it from

<UserControl x:Class="MyNamespace.XAMLControl1" ...>
    ...
</UserControl>

To

<my:BaseControl x:Class="MyNamespace.XAMLControl1"
                xmlns:my="clr-namespace:MyNamespace" ...>
    ...
</my:BaseControl>

The my:BaseControl part is underlined in squiggly blue, so when I hover it, IntelliSense says

The name "BaseControl" does not exist in the namespace "clr-namespace:MyNamespace".

And the compiler gives me the strange errors

  1. Closing tag for element '<m>' was not found.

  2. The type 'm' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.

  3. The name "BaseControl" does not exist in the namespace "clr-namespace:MyNamespace".

Yes, that's "The type 'm' was not found". I don't see where I'm trying to use a type named m anywhere. I think this is an unrelated compiler bug, but I thought I'd mention it. And also I'm definitely sure the type BaseControl does exist in the namespace MyNamespace. Intellisense comes up with no suggestions after I type the my:.

What can I do to fix this problem? I am using Visual Studio 2012 Express for Windows Desktop (7).

Community
  • 1
  • 1
Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • I doubt there is a bug in the compiler... Check you didn't forget any closing bracket or XAML marker. + Try clean your whole solution and rebuild it first. – Guillaume Oct 25 '12 at 04:26
  • @Guillaume there is definitely a bug in the compiler with regard to the names used error messages, even though I'm sure it should really error. I just rebuilt the whole solution, no help. Sometimes the error messages are correct, and sometimes not. – Seth Carnegie Oct 25 '12 at 04:29

3 Answers3

3

Its seems that you have to use your own BaseControl using separate dll. When you start your xaml file, you start to use the my namespace, and you declare it later in your xaml. It is the same if you want to use StaticResource before it was declared. But when you separate your BaseControl to another project to get a new dll, it will be compiled before it used.

stukselbax
  • 5,855
  • 3
  • 32
  • 54
  • Even if using a separate DLL you will have to declare the namespace after using it in the `Control` name declaration. This won't help, you can definitely refer to a namespace within the same assembly in a XAML file. – Guillaume Oct 25 '12 at 04:36
  • However, I think the assembly may require to be compiled once first before being able to use the namespace in question in a `Control`, this is right. – Guillaume Oct 25 '12 at 04:40
  • @Guillaume, have you ever try to use third party controls in your project? Are you tried my suggestion? Why are you so sure? – stukselbax Oct 25 '12 at 04:42
  • Amazing, this works perfectly. This is an annoying and unintuitive behaviour, I wonder why I couldn't find anything on it on Google and why the tutorials I read never mentioned this. Thanks very much. – Seth Carnegie Oct 25 '12 at 04:45
  • I didn't try your solution now, but I've already used 3rd party DLLs yes. And I've also used `Control`s declared locally in my assembly and it compiled. And it's definitely possible. – Guillaume Oct 25 '12 at 04:45
  • @Guillaume, yours `Control`s using can differ from what @SethCarnegie wants. You probably use it inside the root **xaml** tags, so all your namespaces was available for them. I think that you will came to the same result if you wants to use your `Control` as the root of the **xaml** file. – stukselbax Oct 25 '12 at 04:53
  • @stukselbax My understanding of the question is "how to use a custom `Control` inheriting from another custom `Control`." ie. with the namespace of the parent `Control` in the root tag, before it is actually declared. If that's it, I did it and it works fine provided you compile first before actually using the parent control. But I may have missed some points in the question. I don't get why you would have to have your `Control`s in different assemblies. – Guillaume Oct 25 '12 at 05:00
  • @Guillaume well for some reason it only worked when I did that. Also, how can one "compile first before actually using the parent control"? If it's such that it uses itself in compiling itself (so it has to have a "previous version" to use) I compiled once with the base class defined but without using it anywhere, and it still didn't work when I added the inheritance. – Seth Carnegie Oct 25 '12 at 15:32
  • @SethCarnegie I don't know why this works (in my case actually). As I was saying above, there may also be something I misunderstood in your question, or there are some other details that you didn't specify and which are different in my case but that are important for that matter. – Guillaume Oct 29 '12 at 00:13
2

I found this question when I faced the same issue with the same compiler message. Maybe I missed something in the discussion, but for me the solution was to add the implementing Dll specification like:

xmlns:my="clr-namespace:MyNamespace;assembly=MyDll"
Chris
  • 44,602
  • 16
  • 137
  • 156
MumpiH
  • 73
  • 1
  • 5
0

No need for separate dlls its really easy actually

namespace MyNameSpace.UserControls
{
      public class BaseControl : UserControl { //all the good common stuff... } 
}

then

namespace MyNameSpace.UserControls
{
      public sealed partial class DerivedControl: BaseControl { //your specific stuff... } 
}

then (for the DerivedControl)

<local:BaseControl x:Class="MyNameSpace.UserControls.DerivedControl"
                                   xmlns:local="using:MyNameSpace.UserControls"

(note, this is for a base class without a matching xaml file)

See How do you specify a different base class in .xaml files (Silverlight)?

Community
  • 1
  • 1
MemeDeveloper
  • 6,457
  • 2
  • 42
  • 58