大家下午好。我意识到这个主题可能在其他地方有所涉及。
我在 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>
在定义这样的自定义控件时,我应该为控件中的对象设置名称吗?
<Button x:Name="rs422DevCheckBtn" Content="Check" />
当我的应用程序检测到设备时,我想将这些控件之一添加到 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 也是如此。如果这篇文章复制了其他文章的内容,我深表歉意。我已经研究了大约一周,需要继续前进。
提前致谢!
对于你的第一个问题,只有当你需要引用它们时才需要名称。这可以从绑定或隐藏代码等内容中引用。
您的第二个问题已加载。有很多方法可以解决这个问题,如果没有意见很难给出答案。我认为最常见的是一种称为 MVVM(模型-视图-视图模型)的设计模式,其中通过绑定将控件松散地耦合到属性。关于 MVVM 有很多资源,这不是我能在这里做的事情。
您多次说过“自定义控件”,实际上这是一个用户控件。它们是有区别的。自定义控件(在某些基于 XAML 的 UI 中有时称为模板化控件)通常继承自 Control 并提供控件模板。