在IronPython中创建自定义WPF控件:由标准控件组合而成的控件

3 投票
1 回答
1189 浏览
提问于 2025-04-16 08:12

我看过这里其他关于自定义控件创建的问题,还有一些网上的资源,但我还是搞不清楚怎么创建一个不需要C#后台代码的自定义控件。因为我的项目是纯IronPython的,我不知道怎么把C#的后台代码和它结合起来。

其实我想做的并不复杂;没有什么复杂的样式或者渲染转换之类的。我只是想把我已有的一些控件组合成一个复合控件,这样我就可以按需添加或删除这些复合控件。例如,我有一个这样的GroupBox:

你可以看到,这只是一个GroupBox,头部有一个文本框和一个下拉框,主体是一个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来实现这个呢?

1 个回答

1

我觉得还有更好的方法,所以我会把这个问题留着,但我在IronPython中实现自定义控件的动态添加,最终是通过把XAML放在一个单独的文件里来完成的。我用XamlReader.Load()来加载这个文件,然后把返回的结果存储在一个新对象里。这个对象就成了控件,可以添加到GridDockPanel或者其他地方。花了我一段时间才明白,原来我可以用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>
    ...

撰写回答