从XML动态创建WPF控件并堆叠它们

时间:2013-01-29 15:48:03

标签: c# wpf xml-serialization

我想要完成一系列包含完整测试的步骤。其中一些步骤是自动的(因此是信息性的),而其他步骤则需要用户交互。测试步骤在编译时是未知的,它们正在使用MEF加载。

目前我有类似

的东西
public abstract class TestRunnerBase
{
    public abstract void Run();
}

使用这样的步骤列表:

 List<TestRunnerBase> Steps = new List<TestRunnerBase>();

因此,所有代表可序列化测试的数据到目前为止都可以正常工作。然而,我真正需要的是用户从XML加载测试,然后引导他们浏览显示屏幕上的信息并收集结果的选项。

但是试图找出如何为编译时未知的数据创建控件,最终导致我对最佳方法产生了一些困难。

我正在考虑这样做我会有一个自定义控件列表(1步骤),GUI将显示第一步,等待该控件完成(我在这里想到一个凸起的事件可能会起作用? )然后显示下一个(如果可用),依此类推,直到测试完成。

那么在WPF中可以这样做吗?你能在WPF中创建一堆控件,每个控件可以将同一个事件引发到父容器,还是有更好的方法呢?

但是,如果我也使用抽象类,那么我就不能从它派生一个控件,当然也没有C#中的多重继承。

2 个答案:

答案 0 :(得分:2)

我将使用MVVM并创建一个viewmodel,它了解如何导航步骤列表,提供向导类型结构(prev / next)并公开当前步骤。

我假设你有不同类型的潜在未知步骤,你有一组具体的输入选项(bool,text,date,int等),那么你可以在TestRunnerBase上使用一个抽象属性来识别哪种类型的使用必须覆盖的枚举需要输入(或不输入)。

然后,您可以使用数据窗口和/或数据触发器来控制测试的每个步骤显示的内容。主视图模型可以检查条件是否适合进入下一步(可能是对测试的验证)。

一些伪造的代码让你思考:

public enum TestInput
{
    None,
    Bool,
    Text
}

public abstract class TestRunnerBase
{
    public abstract TestInput TestInput { get; }
    public bool BoolInput { get; set; }
    public string TextInput { get; set; }
    public abstract bool CanRun()
    public abstract void Run();
}

public class MainViewModel
{
    List<TestRunnerBase> Steps = new List<TestRunnerBase>();
    public TestRunnerBase CurrentStep {get;set;};

    public MainViewModel()
    {
        //loads the Steps
        CurrentStep = Steps
    }

    public Command RunStepCommand
    {
        if (CurrentStep.CanRun())
        {
            CurrentStep.Run();
            CurrentStep = Steps.Next(); //you get the idea
        }
    }
}

对于您的XAML,您可以将ContentPresenter绑定到CurrentStep并使用datatemplate(可能还有数据触发器)来控制用户可见的内容(当然还有绑定到UI)。

答案 1 :(得分:1)

在WPF中,您可以使用XAML动态创建控件。只需创建一个包含所需布局的XAML代码段(以编程方式或手动方式),然后使用XamlReader.Parse从代码段创建整个树。然后可以将返回的对象插入窗口的可视树中的某个位置。

要从XamlReader生成的可视树生成事件,您可以使用routed events