简体   繁体   中英

How does xaml set content of a custom control?

Apologies for the rather vague title - please change if you can word it better. I'm not certain how XAML sets the content of a control, it appear there is something different happening behind the scenes than a simple Content = X , but I'm not sure what.

See, if I have the following:

Custom Control:

using System;
using System.Windows.Controls;

namespace DemoWPF
{
    public class MyControl : UserControl
    {
        public MyControl()
        {
            base.Content = new Label() { Content = "Real Content" };
        }
        public new Object Content
        {
            get;
            set;
        }
    }
}

This does very little but override the Content property - essentially rendering it useless and making it only hold a Label displaying "Real Content".

If I then want to use this custom control, I can do so in two ways, without xaml and with xaml:

Use case 1 - Window cs file (without xaml)

using System.Windows;
using System.Windows.Controls;

namespace DemoWPF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Content = new MyControl() { Content = new Label() { Content = "Should not show" } };
        }
    }
}

This works as I expect - the Content of the window (obviously only at runtime as no designer is used) is shown to be the label "Real Content", and the "Should Not Show" label doesn't made an appearance.

Use case 2 - Window (with xaml)

However, if instead of the above, I set the content through XAML, then both the design and run-time show the "Should Not Show" label, and the "Real Content" appears to be ignored:

<Window x:Class="DemoWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DemoWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <local:MyControl>
        <Label>Should not show</Label>
    </local:MyControl>

</Window>

What is the reasoning for this, and what is xaml doing different than demonstrated in Use Case 1 ?

This happens because there is a ContentProperty attribute declaration at the ContentControl class declaration:

System.Windows.Markup.ContentProperty("Content")
public class ContentControl ...

which set makes a XAML expression like

<local:MyControl>
    <Label>Should not show</Label>
</local:MyControl>

set the base class' Content property, not your new one.

You would have to write

<local:MyControl>
    <local:MyControl.Content>
        <Label>Should not show</Label>
    </local:MyControl.Content>
</local:MyControl>

As a note, you should entirely avoid to hide any WPF control properties. It only adds confusion for no benefit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM