本节内容需要读者已掌握MVVM绑定的基本知识,详见020篇文章,这里不再重复基础知识,我们是接上期内容继续优化我的mvvm底层类封装

假设我有一个需求,上图软件中,然后我选择了"标准梯形螺纹"那么,我需要粗选螺纹中径这个combox选项是可见的,如果我选择了"非标螺纹",则需要隐藏掉combox,防止用户误操作

这是一个非常典型的 MVVM 场景。在 WPF 中,您不能直接将一个字符串或布尔值绑定到 Visibility 属性,因为 Visibility 属性需要一个 System.Windows.Visibility 枚举值(Visible、Hidden 或 Collapsed)。
UI界面的combox控件显示/隐藏状态是由三个枚举来控制的(Visible、Hidden 或 Collapsed),
故后台控制类的属性并不能直接用来控制combox
要解决这个问题,您需要使用 值转换器 (Value Converter) ,它实现了 IValueConverter 接口。
下面是实现这个功能的详细步骤和代码示例。
一.MVVM绑定类增加一个string属性用来控制
cs
private string _key= "Visible";
public string Key
{
get { return _key; }
set
{
if (_key != value)
{
_key = value;
OnPropertyChanged(nameof(Key));//订阅自己更新
}
}
}
步骤二:创建值转换器类 (KeyToVisibilityConverter)
这个转换器的作用是将您的 Key 属性的值(例如,一个字符串)转换为 WPF 认识的 Visibility 枚举值。
假设:
- 如果
Key的值是"Visiblel",则 ComboBox 显示 (Visible)。 - 否则,信号若是"Hide" 隐藏 (
Collapsed)。
新建Control文件夹,把值转换器类放到这个文件夹内
类继承值转换器接口: IValueConverter
把实现这个接口的方法改下如下:
cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace NX_Openg.Control
{
public class KeyToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// 1. 检查传入的值是否为字符串
if (value is string keyString)
{
// 2. 在这里定义控制逻辑
// 示例:如果 Key 是 "Hide",则返回 Collapsed
if (keyString == "Hide")
{
return Visibility.Collapsed;//隐藏并清除界面占位
}
}
// 3. 默认返回 Visible(显示)
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
步骤三:在 XAML 中使用转换器
1.在 XAML 文件的顶部或 App.xaml 中引入命名空间(假设您的转换器在 NX_Openg.Control 中)。
XML
xmlns:cjp="clr-namespace:NX_Openg.Control"
2.将转换器实例化为资源,资源路径在cjp映射的文件夹NX_Openg.Control下,资源key自定义命名
为KeyVisConverter
XML
<Window.Resources>
<cjp:KeyToVisibilityConverter x:Key="KeyVisConverter"/>
</Window.Resources>
3.将 ComboBox3 的 Visibility 属性绑定到 Screw类对象ScrewIifo的Key 属性,并使用刚刚创建的转换器KeyVisConverter。ScrewIifo是我的MianViewMode的mvvm绑定的子类对象,见020篇文章
XML
Visibility="{Binding ScrewInfo.Key, Converter={StaticResource KeyVisConverter}}"
完整的界面代码如下:
XML
<Window x:Class="NX_Openg.HomePage"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NX_Openg"
xmlns:cjp="clr-namespace:NX_Openg.Control"
d:DataContext="{d:DesignInstance Type=local:MainViewModel}"
mc:Ignorable="d"
Title="机械设计" Height="900" Width="1450" >
<Window.Resources>
<cjp:KeyToVisibilityConverter x:Key="KeyVisConverter"/>
</Window.Resources>
<Grid Margin="0,4,0,-4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="669*"/>
<ColumnDefinition Width="135*"/>
<ColumnDefinition Width="646*"/>
</Grid.ColumnDefinitions>
<TabControl Grid.ColumnSpan="3">
<TabItem Header="丝杆传动">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Background="#FFFFE0">
<TextBlock HorizontalAlignment="Left" Margin="10,39,0,0" TextWrapping="Wrap" Text="螺杆材质:" VerticalAlignment="Top"/>
<ComboBox Name="combox1" HorizontalAlignment="Left" Margin="91,35,0,0" VerticalAlignment="Top" Width="120" SelectionChanged="combox1_SelectionChanged">
<ComboBoxItem Content="工具钢9Mn2V" />
<ComboBoxItem Content="工具钢CrWMn"/>
<ComboBoxItem Content="氮化钢38CrMoA1A"/>
<ComboBoxItem Content="40Cr"/>
<ComboBoxItem Content="45钢" IsSelected="True"/>
</ComboBox>
<TextBlock HorizontalAlignment="Left" Margin="223,39,0,0" TextWrapping="Wrap" Text="螺母材质:" VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" Margin="20,5,0,0" TextWrapping="Wrap" Text="{Binding ScrewInfo.Note1}" VerticalAlignment="Top" Foreground="Red"/>
<ComboBox Name="combox2" HorizontalAlignment="Left" Margin="303,35,0,0" VerticalAlignment="Top" Width="120" SelectionChanged="combox2_SelectionChanged">
<ComboBoxItem Content="青铜"/>
<ComboBoxItem Content="耐磨铸铁"/>
<ComboBoxItem Content="钢"/>
<ComboBoxItem Content="黄铜" IsSelected="True"/>
</ComboBox>
<RadioButton x:Name="RedRadio1" Content="标准梯螺纹" GroupName="GB" HorizontalAlignment="Left" Margin="442,39,0,0" VerticalAlignment="Top" IsChecked="True" Checked="RedRadio1_Checked"/>
<RadioButton Content="非标梯螺纹" GroupName="GB" HorizontalAlignment="Left" Margin="538,39,0,0" VerticalAlignment="Top" Checked="RedRadio1_Checked"/>
<TextBlock HorizontalAlignment="Left" Margin="10,67,0,0" TextWrapping="Wrap" Text="初选螺纹中径:" VerticalAlignment="Top"/>
<ComboBox Name="combox3" HorizontalAlignment="Left" Margin="91,63,0,0" VerticalAlignment="Top" Width="120"
Visibility="{Binding ScrewInfo.Key, Converter={StaticResource KeyVisConverter}}"
SelectionChanged="combox3_SelectionChanged">
<ComboBoxItem Content="8" IsSelected="True"/>
<ComboBoxItem Content="10"/>
<ComboBoxItem Content="12"/>
<ComboBoxItem Content="16"/>
<ComboBoxItem Content="20"/>
<ComboBoxItem Content="24"/>
</ComboBox>
<TextBlock HorizontalAlignment="Left" Margin="223,67,0,0" TextWrapping="Wrap" Text="自定义中径:" VerticalAlignment="Top"/>
<TextBox Name="text_d2" HorizontalAlignment="Left" Margin="303,67,0,0" TextWrapping="Wrap" Text="8" VerticalAlignment="Top" Width="120"/>
</Grid>
<Grid Grid.Row="0" Grid.Column="1" ></Grid>
<Button Grid.Row="1" Grid.Column="1" Content="生成螺母"/>
</Grid>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
</TabControl>
</Grid>
</Window>
四.在后台代码处理它显示隐藏的时机
当radio选中的项目变化时,修改key的值,经过转换器转为枚举后控制ui界面显示和隐藏
cs
private void RedRadio1_Checked(object sender, RoutedEventArgs e)
{
// 检查是否选中
if (RedRadio1.IsChecked == true)
{
home.ScrewInfo.GB = true;//选择了标准螺纹
home.ScrewInfo.Key = "Visible";//combox3显示
}
else {
home.ScrewInfo.GB = false;
home.ScrewInfo.Key = "Hide";//combox3隐藏
}
}