Skip to main content
 首页 » 编程设计

python之在 IronPython 中创建自定义 WPF 控件 : a control made up out of standard controls

2025年05月04日13zlslch

我查看了此处的其他自定义控件创建问题以及其他在线资源,但我不知道如何创建不需要 C# 代码隐藏文件的自定义控件。由于我的项目是纯 IronPython,我不知道如何将背后的 C# 代码与其集成。

我想做的事情并没有那么复杂;没有凌乱的样式或渲染转换或任何东西。我只是想创建一个我拥有的一堆现有控件的复合控件,以便我可以按程序添加/删除这些复合控件。例如,我有这个 GroupBox:

如您所见,它只是一个 GroupBox,在 Header 中有一个 TextBox 和一个 ComboBox,其主体由一个包含一些 CheckBox 的 UniformGrid 填充。这是 XAML:

<GroupBox Name="DO1"> 
    <GroupBox.Header> 
        <DockPanel> 
            <TextBlock VerticalAlignment="Center">DO1</TextBlock> 
            <ComboBox Name="DO1DeviceList" Margin="3 0 0 0" ItemsSource="{Binding DOtable}"> 
            </ComboBox> 
        </DockPanel> 
    </GroupBox.Header> 
    <UniformGrid Rows="1"> 
        <StackPanel> 
            <Label Content="3W1L" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <CheckBox Name="DO1o1" IsChecked="{Binding o1}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <Label Content="1" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
        </StackPanel> 
        <StackPanel> 
            <Label Content="3W3V" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <CheckBox Name="DO1o2" IsChecked="{Binding o2}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <Label Content="2" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
        </StackPanel> 
        <StackPanel> 
            <Label Content="Ni" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <CheckBox Name="DO1o3" IsChecked="{Binding o3}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <Label Content="3" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
        </StackPanel> 
        <StackPanel> 
            <Label Content="2W1" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <CheckBox Name="DO1o4" IsChecked="{Binding o4}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <Label Content="4" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
        </StackPanel> 
        <StackPanel> 
            <Label Content="Vac2" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <CheckBox Name="DO1o5" IsChecked="{Binding o5}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <Label Content="5" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
        </StackPanel> 
        <StackPanel> 
            <Label Content="3W4V" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <CheckBox Name="DO1o6" IsChecked="{Binding o6}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <Label Content="6" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
        </StackPanel> 
        <StackPanel> 
            <Label Content="Cu" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <CheckBox Name="DO1o7" IsChecked="{Binding o7}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <Label Content="7" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
        </StackPanel> 
        <StackPanel> 
            <Label Content="3W2L" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <CheckBox Name="DO1o8" IsChecked="{Binding o8}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
            <Label Content="8" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
        </StackPanel> 
    </UniformGrid> 
</GroupBox> 

我读过有关控件合成的内容,即将一堆控件组合成一个控件。我想让整个 GroupBox 成为一个我可以按程序添加或删除的控件。我如何使用 IronPython 完成此操作?

请您参考如下方法:

我仍然觉得有更好的方法,所以我会保留这个问题,但我最终在 IronPython 中运行时添加自定义控件的方法是简单地将 XAML 放在一个单独的文件中,加载它使用 XamlReader.Load() 并将返回值存储在新对象中。该对象成为控件,然后可以将其添加到 Grid、DockPanel 或您拥有的任何东西。我花了一段时间才意识到我可以使用 XamlReader 从 XAML 构建任何控件,而不仅仅是 Window。

with File.OpenRead("MyControl.xaml") as xamlfile: 
    newcontrol = System.Windows.Markup.XamlReader.Load(xamlfile) 
 
ui.FindName("MyDockPanel").Children.Add(newcontrol) 

XAML 文件仅包含上述 GroupBox 标记以及用于建立正确命名空间的 xmlns 属性。

<GroupBox Name="DO1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <GroupBox.Header> 
    ...