在WPF窗口中创建一个公共结构(主题)

时间:2015-06-19 12:26:59

标签: c# wpf xaml

我刚刚创建了一个Windows窗体应用程序来从基础窗体继承控件,它工作正常。

在WPF XAML中是否可以将控件从基本表单继承到另一个表单?

当我在visual studio中尝试时,我显示错误:"' parentchild.MainWindow'不能是XAML文件的根,因为它是使用XAML"定义的。

我的Basewindow cs代码:

namespace parentchild
    {
    public partial class BaseWindow : Window
        {
            public BaseWindow()
            {
                InitializeComponent();
            }
        }
}

我的Basewindow xaml代码:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon" x:Class="parentchild.BaseWindow"
        Title="BaseWindow" Height="350" Width="525">
    <Grid>
        <StatusBar HorizontalAlignment="Left" Height="35" Margin="0,285,0,0" VerticalAlignment="Top" Width="517">
            <Label Content="Label"/>
            <Label Content="Label"/>
        </StatusBar>
    </Grid>
</Window>

我的childwindow cs代码:

namespace parentchild
{
    public partial class childwindow : BaseWindow
    {
        public childwindow()
        {
            InitializeComponent();
        }
    }
}

我的childwindow xaml代码:

   <mn:BaseWindow x:Class="parentchild.childwindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mn="clr-namespace:parentchild"
            Title="childwindow" Height="300" Width="300">
        <Grid>

        </Grid>
    </mn:BaseWindow>

我通过创建用户控件并将其应用到所有窗口找到了另一种解决方案。这是正确的方法吗?

或者任何人都有解决方案来为所有Xaml窗口创建一般主题/结构。

请为我提供解决此问题的解决方案。

2 个答案:

答案 0 :(得分:1)

您不能从已在xaml中定义的类继承。我可能会创建一个UserControl并将其用作任何Window中的“基本容器”,以获得状态栏。如果您打算制作一个基本窗口,您可以尝试这样的事情:

仅在代码中定义基本窗口:

public class MyWindowBase : Window
    {
        private ContentControl contentControl;

        public MyWindowBase()
        {
            this.CreateContent();
        }

        public Object BaseContent
        {
            get { return this.contentControl.Content; }
            set { this.contentControl.Content = value; }
        }

        private void CreateContent()
        {
            var grid = new Grid();
            var row1 = new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) };
            var row2 = new RowDefinition() { Height = GridLength.Auto };
            grid.RowDefinitions.Add(row1);
            grid.RowDefinitions.Add(row2);

            var statusBar = new StatusBar() { Height = 35, Background = Brushes.Blue }; // Initialize the status bar how you want.
            Grid.SetRow(statusBar, 1);

            this.contentControl = new ContentControl();

            grid.Children.Add(this.contentControl);
            grid.Children.Add(statusBar);

            base.Content = grid;
        }
    }

在xaml中使用基本窗口,如下所示:

<WpfApplication7:MyWindowBase xmlns:WpfApplication7="clr-namespace:WpfApplication7"  x:Class="WpfApplication7.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="500">
    <WpfApplication7:MyWindowBase.BaseContent>
        <Button>
            Something
        </Button>
    </WpfApplication7:MyWindowBase.BaseContent>    
</WpfApplication7:MyWindowBase> 

当然,基类还有改进的余地,比如将BaseContent作为依赖属性,但我认为它证明了主要的想法。

答案 1 :(得分:0)

看起来您基本上是在尝试创建一个扩展Window的自定义控件。在WPF中创建自定义控件是一个复杂的主题,因为在决定如何实现自定义控件时需要考虑很多。看看这篇谈论这篇文章的文章:

Control Authoring Overview

最有可能的是,您实际上并不想要自定义控件,而是自定义ControlTemplate(在xaml中创作),它重新定义了您希望窗口的外观。您可以在Style中定义模板,并将该样式应用于您想要的任何Window。在答案中尝试解释这一点很多,所以你应该阅读控制模板如何工作以及它们如何有用。

如果您决定需要向自定义窗口添加新属性,那么您需要创建一个扩展Window的新类,并将这些属性添加为dependency properties(现在您有一个自定义控件)。然后,您可以在自定义ControlTemplate中使用这些属性来执行您希望他们执行的操作。

在WPF中工作完全不像在Windows窗体中工作。如果您尝试将在Windows窗体中学习的技术和实践应用于WPF应用程序,您将会遇到很多麻烦。几年前我进行了这种转换,我的建议是根据您从Windows Forms中了解的内容,不做任何关于WPF的假设。它们是完全不同的系统,具有不同的处理方式。