views:

237

answers:

1

(this question is a refinement of my other question on this topic which was a bit complicated but I really want to understand why this doesn't work so here's a more straight-forward example)

WHAT I WANT TO DO: create a simple class (no XAML) in one project which inherits a WPF UserControl (with XAML) in another project.

Here is my inheriting class in my main project:

EmployeeEditor.cs:

using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;
using CoreApp;

namespace TestInheritUserControl234
{
    class EmployeeEditor : BaseEditor
    {
        public EmployeeEditor()
        {
            TextBlock tb = new TextBlock();
            tb.Text = "This was added in EmployeeEditor";
            tb.Foreground = new SolidColorBrush(Colors.Blue);
            EditorContent.Children.Add(tb);
        }
    }
}

And here is my base class in my second project, notice it has x:Name="EditorContent":

BaseEditor.xaml:

<UserControl x:Class="CoreApp.BaseEditor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <StackPanel x:Name="EditorContent" Margin="5">
        <TextBlock x:Name="TheMessage" Text="This was added in BaseEditor XAML."/>
    </StackPanel>
</UserControl>

BaseEditor.xaml.cs:

using System.Windows.Controls;
namespace CoreApp
{
    public partial class BaseEditor : UserControl
    {
        public BaseEditor()
        {
            InitializeComponent();

            TextBlock tb = new TextBlock();
            tb.Text = "This was added in BaseEditor code-behind.";
            EditorContent.Children.Add(tb);
        }
    }
}

The problem is when this is run, I get the error The name 'EditorContent' does not exist in the current context.

However, if all classes are in one project, it runs fine.

Why would it be that you can inherit a class over project boundaries, but not its attached XAML?

A: 

Default protection level is internal if I'm not mistaken, that's the problem in this case. To fix it change StackPanel declaration as follows:

<StackPanel x:Name="EditorContent" x:FieldModifier="public" Margin="5">

UPDATE: This brings up another problem indeed, which seems to be a limitation of WPF: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/4f6385ea-a176-489e-9f13-0c812195e323 Microsoft specifically prevents inheriting XAML-defined classes from another assembly for some reason. Quote from System.Windows.Application.LoadComponent():

if ((info2 == null) || (info2.Assembly != component.GetType().Assembly))
{
    throw new Exception(SR.Get("UriNotMatchWithRootType", new object[] { component.GetType(), resourceLocator }));
}
Stanislav Kniazev
If I do that, it tells me: "The component "TestInheritUserControl234.CustomerEditor" does not have a resource which can be identified by "/CoreApp;component/baseeditor.xaml". (ORIGINAL: "Die Komponente "TestInheritUserControl234.CustomerEditor" verfügt nicht über eine Ressource, die vom URI "/CoreApp;component/baseeditor.xaml" identifiziert wird.")
Edward Tanguay