WPF 自定义控件的使用和访问

问题描述 投票:0回答:1

大家下午好。我意识到这个主题可能在其他地方有所涉及。

我在 C# 方面很有经验,但大部分经验是使用控制台应用程序、Win Forms,而不是 GUI 的 WPF,也不是 MVVM。我正在编写一个程序来检测 USB-RS422 设备,然后为发现的每个设备提供用户配置选项。系统将有 1->8 个这样的设备,最初是 1->4 个,所以我手动为每个设备创建了布局。现在数量已经增加,我尝试创建自定义用户控件,但我在一些概念上遇到了困难。

这是我的自定义控件的代码:rs422DeviceControlGroup.xaml

<UserControl
x:Class="EngineeringLabUi.rs422DeviceControlGroup"
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:internal="clr-namespace:rs422DeviceControlGroup"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
    <GroupBox
        Grid.Row="1"
        Grid.Column="0"
        Header="Test"
        Style="{StaticResource GroupBoxStyle}">
        <StackPanel x:Name="rs422DevStackPnl" Orientation="Vertical">
            <Border BorderThickness="1">
                <StackPanel Orientation="Horizontal">
                    <CheckBox x:Name="rs422DevEditCkBx" Content="Edit" />
                    <CheckBox x:Name="rs422DevUseCkBx" Content="Use" />
                    <TextBlock Text="Read Type" />
                    <ComboBox x:Name="rs422DevReadTypeComboBox" SelectedIndex="0" />
                    <TextBlock Text="Write Type" />
                    <ComboBox x:Name="rs422DevWriteTypeComboBox" SelectedIndex="0" />
                </StackPanel>
            </Border>
            <Border BorderThickness="1">
                <StackPanel Orientation="Horizontal">
                    <Border BorderThickness="1">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Baud" />
                            <ComboBox x:Name="rs422DevBoadRatesComboBox" SelectedIndex="0" />
                        </StackPanel>
                    </Border>
                    <Border BorderThickness="1">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Parity" />
                            <ComboBox x:Name="rs422DevParityComboBox" SelectedIndex="0" />
                        </StackPanel>
                    </Border>
                    <Border BorderThickness="1">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Data Bits" />
                            <ComboBox x:Name="rs422DevDataBitsComboBox" SelectedIndex="0" />
                        </StackPanel>
                    </Border>
                    <Border BorderThickness="1">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Stop Bits" />
                            <!--  stop bits value of None is not currently supported  -->
                            <ComboBox x:Name="rs422DevStopBitsComboBox" SelectedIndex="1" />
                        </StackPanel>
                    </Border>
                    <Border BorderThickness="1">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="FCC Position" />
                            <ComboBox x:Name="rs422DevFccPositionComboBox" SelectedIndex="0" />
                        </StackPanel>
                    </Border>
                    <Border BorderThickness="1">
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Status" />
                            <Ellipse x:Name="rs422DevStatusEllipse" />
                            <Button x:Name="rs422DevCheckBtn" Content="Check" />
                        </StackPanel>
                    </Border>
                </StackPanel>
            </Border>
        </StackPanel>
    </GroupBox>
</Grid>

这是它在设计视图中的呈现方式

  1. 在定义这样的自定义控件时,我应该为控件中的对象设置名称吗?

    <Button x:Name="rs422DevCheckBtn" Content="Check" />

  2. 当我的应用程序检测到设备时,我想将这些控件之一添加到 TabItem,但我不确定如何深入了解每个复选框、组合框、椭圆和按钮。

我还在App.xaml文件中创建了样式,如下所示:

<Application
x:Class="EngineeringLabUi.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:EngineeringLabUi"
StartupUri="MainWindow.xaml">

<Application.Resources>
    <!--#region buttonStyle-->
    <Style TargetType="Button">
        <Setter Property="Padding" Value="2" />
        <Setter Property="Margin" Value="1,1,1,1" />
        <Setter Property="Height" Value="auto" />
        <Setter Property="Width" Value="auto" />
        <Setter Property="IsEnabled" Value="False" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
    <!--#endregion buttonStyle-->
    <!--#region borderStyle-->
    <Style TargetType="Border">
        <Setter Property="Padding" Value="2" />
        <Setter Property="Margin" Value="2" />
        <Setter Property="BorderBrush" Value="Black" />
        <Setter Property="BorderThickness" Value="2" />
        <Setter Property="CornerRadius" Value="6" />
        <Setter Property="Opacity" Value="100" />
    </Style>
    <!--#endregion borderStyle-->
    <!--#region comboBoxStyle-->
    <Style TargetType="ComboBox">
        <Setter Property="Padding" Value="5" />
        <Setter Property="Margin" Value="2" />
        <Setter Property="Height" Value="auto" />
        <Setter Property="Width" Value="auto" />
        <!--< debug />-->
        <!--<Setter Property="IsEnabled" Value="False" />-->
        <Setter Property="IsEnabled" Value="True" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
    <!--#endregion comboBoxStyle-->
    <!--#region labelStyle-->
    <Style TargetType="Label">
        <Setter Property="Padding" Value="1" />
        <Setter Property="Margin" Value="1,1,1,1" />
        <Setter Property="Height" Value="auto" />
        <Setter Property="Width" Value="auto" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="FontWeight" Value="Bold" />
    </Style>
    <!--#endregion labelStyle-->
    <!--#region textBlockStyle-->
    <Style TargetType="TextBlock">
        <Setter Property="Padding" Value="1" />
        <Setter Property="Margin" Value="3,3,3,3" />
        <Setter Property="Height" Value="auto" />
        <Setter Property="Width" Value="auto" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="TextDecorations" Value="Underline" />
        <!--<Setter Property="bo" Value="Underline" />-->
    </Style>
    <!--#endregion textBlockStyle-->
    <!--#region groupBoxStyle-->
    <Style x:Key="GroupBoxStyle" TargetType="{x:Type GroupBox}">
        <Setter Property="BorderBrush" Value="#D5DFE5" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupBox}">
                    <Grid SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="auto" />
                            <ColumnDefinition Width="auto" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="auto" />
                            <RowDefinition Height="auto" />
                        </Grid.RowDefinitions>
                        <Border
                            x:Name="Header"
                            Grid.Row="0"
                            Grid.Column="1"
                            Padding="3,1,3,0">
                            <ContentPresenter
                                ContentSource="Header"
                                RecognizesAccessKey="True"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </Border>
                        <ContentPresenter
                            Grid.Row="2"
                            Grid.Column="1"
                            Grid.ColumnSpan="2"
                            Margin="{TemplateBinding Padding}"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <!--#endregion groupBoxStyle-->
    <!--#region checkBoxStyle-->
    <Style TargetType="CheckBox">
        <Setter Property="Padding" Value="0" />
        <Setter Property="Margin" Value="10,1,1,1" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <!--< debug />-->
        <!--<Setter Property="IsEnabled" Value="False" />-->
        <Setter Property="IsEnabled" Value="True" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
    </Style>
    <!--#endregion checkBoxStyle-->
    <!--#region ellipseStyle-->
    <Style TargetType="Ellipse">
        <Setter Property="Height" Value="15" />
        <Setter Property="Margin" Value="1,1,1,1" />
        <Setter Property="StrokeThickness" Value="3" />
        <Setter Property="Width" Value="15" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="IsEnabled" Value="False" />
        <Setter Property="Fill" Value="Gray" />
        <Setter Property="Stroke" Value="Black" />
    </Style>
    <!--#endregion ellipseStyle-->
    <!--#region tabControltyle-->
    <Style TargetType="TabControl">
        <Setter Property="Padding" Value="0" />
        <Setter Property="Margin" Value="1,1,1,1" />
        <Setter Property="FontSize" Value="10" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Stretch" />
    </Style>
    <!--#endregion tabControltyle-->
    <!--#region tabItemStyle-->
    <Style TargetType="TabItem">
        <Setter Property="Padding" Value="3.5" />
        <Setter Property="Margin" Value="-2,0,-2,0" />
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="Height" Value="22" />
    </Style>
    <!--#endregion tabItemStyle-->
    <!--#region menuItemStyle-->
    <Style TargetType="MenuItem">
        <!--< debug />-->
        <!--<Setter Property="Foreground" Value="#FF020202" />-->
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="Height" Value="22" />
    </Style>
    <!--#endregion menuItemStyle-->
    <!--#region flowDocumentStyle-->
    <Style TargetType="FlowDocument">
        <Setter Property="ColumnRuleBrush" Value="Black" />
        <Setter Property="ColumnRuleWidth" Value="1" />
        <Setter Property="IsColumnWidthFlexible" Value="True" />
        <Setter Property="MaxPageWidth" Value="1000" />
        <Setter Property="PageWidth" Value="auto" />
        <Setter Property="MaxPageHeight" Value="700" />
    </Style>
    <!--#endregion flowDocumentStyle-->
    <!--#region gridStyle-->
    <Style TargetType="Grid">
        <Setter Property="MaxHeight" Value="700" />
        <Setter Property="MaxWidth" Value="1400" />
        <Setter Property="Height" Value="auto" />
        <Setter Property="Width" Value="auto" />
        <Setter Property="Background" Value="#FFE5E5E5" />
    </Style>
    <!--#endregion gridStyle-->
    <!--#region richTextBoxStyle-->
    <Style TargetType="RichTextBox">
        <Setter Property="MinHeight" Value="500" />
        <Setter Property="MaxHeight" Value="700" />
        <Setter Property="MinWidth" Value="500" />
        <Setter Property="MaxWidth" Value="1000" />
        <Setter Property="HorizontalScrollBarVisibility" Value="auto" />
        <Setter Property="VerticalScrollBarVisibility" Value="auto" />
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="VerticalContentAlignment" Value="Stretch" />
    </Style>
    <!--#endregion richTextBoxStyle-->
</Application.Resources>

在我的 MainWindow.xaml 中,我可以使用如下所示的控件,但正如我所说,我不确定如何设置自定义控件中对象的属性。另外,这是我第一次制作自定义控件,所以我也想知道我是否做得正确,或者我是否应该做一些不同的事情。我的应用程序目前不是 MVVM,但我确实打算在不久的将来迁移到该架构。

    <!-- this is just a test control to organize the layout I intend to use elsewhere-->
<TabControl Margin="254,127,53,273">
    <TabItem Header="COM 4">
        <Grid Background="#FFE5E5E5">
            <local:rs422DeviceControlGroup x:Name="SomeRs422Device" >
                <!-- I'm not sure what I should do here to access the parts of the control-->
            </local:rs422DeviceControlGroup>
        </Grid>
    </TabItem>
    <TabItem Header="COM 5">
        <local:rs422DeviceControlGroup />
    </TabItem>
</TabControl>

我想一种方法是只拥有一个 TabControl,其中 TabItems 足以容纳 8 个设备,然后在运行时在后面的代码中进行实例化。

我正在寻求一些建议,因为应用程序中的这一点之后的更改将需要进行大量返工,我想在继续之前确保我的方法是具体的。 MVVM 对我来说有些陌生,WPF 也是如此。如果这篇文章复制了其他文章的内容,我深表歉意。我已经研究了大约一周,需要继续前进。

提前致谢!

c# wpf custom-controls
1个回答
0
投票

对于你的第一个问题,只有当你需要引用它们时才需要名称。这可以从绑定或隐藏代码等内容中引用。

您的第二个问题已加载。有很多方法可以解决这个问题,如果没有意见很难给出答案。我认为最常见的是一种称为 MVVM(模型-视图-视图模型)的设计模式,其中通过绑定将控件松散地耦合到属性。关于 MVVM 有很多资源,这不是我能在这里做的事情。

您多次说过“自定义控件”,实际上这是一个用户控件。它们是有区别的。自定义控件(在某些基于 XAML 的 UI 中有时称为模板化控件)通常继承自 Control 并提供控件模板。

© www.soinside.com 2019 - 2024. All rights reserved.