Search code examples
c#xamlxamarinxamarin.forms

Cannot access base class's members in the derived class's XAML in Xamarin Forms


I am having a DialogView class that is derived from a base class Dialog which is again derived from ContentView, ie. DialogView : Dialog : ContentView. I am getting errors that are mentioned later.

Here is my XAML code (DialogView.xaml)

<controls:DialogView xmlns="http://xamarin.com/schemas/2014/forms"
                     ...
                     xmlns:controls="clr-namespace:MyProject.Views.Controls"
                     IsVisible="False"> <!--error: The property 'IsVisible' was not found in 'DialogView'-->

    <ContentView.Content>  <!--error: The attachable property 'Content' was not found in 'ContentView'
        ...
    </ContentView.Content>
</controls:DialogView>

Here is my C# Code (DialogView.xaml.cs)

public class Dialog : ContentView
{
    // Some properties
}

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class DialogView : Dialog  // error: Partial declarations of View must not specify different base classes
{
}

Errors:

  • DialogView class is a partial class that has view defined in XAML. I want to access IsVisible property of it in the XAML, but I cannot access it, I am getting error: The property 'IsVisible' was not found in DialogView. IsVisible is a property of VisualElement which is available in ContentView as it is derived from VisualElement at multiple levels then why is it not available in DialogView as DialogView is derived from ContentView.

  • I also cannot use <ContentView.Content> inside DialogView's XAML. I am getting an error: The attachable property 'Content' was not found in 'ContentView'.

  • I am also getting error Partial declarations of View must not specify different base classes where I am defining public partial class DialogView : Dialog.

In C#, public members of base classes are directly accessible in the derived class as derived class and base class share an is-a relationship. Is that not a case in XAML? How can I access base class's members in derived class while in XAML.


Solution

  • You say that the xaml is in DialogView.xaml. If that's correct, then you've made a mistake.

    The root element's type must be the parent class. Use x:Class to declare the class itself:

    <controls:Dialog xmlns...
        x:Class="YourNamespace.DialogView">
    

    ALTERNATIVE SOLUTION

    Its possible that you are overcomplicating the situation.

    Why do you define both Dialog and DialogView classes, in DialogView.xaml.cs? That is possible, but almost certainly does not do what you want.

    Instead do this:

    1. Add a new ContentView to your project, named Dialog. This will add two files, Dialog.xaml and Dialog.xaml.cs. In those files, put everything you want to exist in all your subclasses of Dialog.

    2. Add another new ContentView to your project, named DialogView. This will add two more files, DialogView.xaml and DialogView.xaml.cs. In the xaml, change <ContentView ... to <controls:Dialog .... In the cs, change public partial DialogView : ContentView to public partial DialogView : Dialog. Thus, your DialogView is now a Dialog. Build Solution (so intellisense will correctly see the parent change from ContentView to Dialog.) Now add to xaml and cs as desired.

    NOTE: At some time in the future (or maybe its already possible in 2022 Preview), I expect it will become possible for VS to directly create a xaml-based control that inherits from your custom view class. Then you won't have to do a kludge like I do above for DialogView, where I first create a ContentView, and then rename the parent class.