021.WPF 以MVVM模式控制combox控件显示/隐藏

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

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

这是一个非常典型的 MVVM 场景。在 WPF 中,您不能直接将一个字符串或布尔值绑定到 Visibility 属性,因为 Visibility 属性需要一个 System.Windows.Visibility 枚举值(VisibleHiddenCollapsed)。

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隐藏
              
            }
           
        }
相关推荐
无心水7 小时前
分布式定时任务与SELECT FOR UPDATE:从致命陷阱到优雅解决方案(实战案例+架构演进)
服务器·人工智能·分布式·后端·spring·架构·wpf
LZL_SQ9 小时前
HCCL测试框架中AllReduce边界条件测试设计深度剖析
wpf·cann
User_芊芊君子1 天前
【分布式训练】CANN SHMEM跨设备内存通信库:构建高效多机多卡训练的关键组件
分布式·深度学习·神经网络·wpf
就是有点傻2 天前
WPF按钮走马灯效果
wpf
zuozewei2 天前
虚拟电厂聚合商平台安全技术体系深度解读
安全·wpf
极客智造2 天前
WPF 自定义控件:AutoGrid 实现灵活自动布局的网格控件
wpf
极客智造2 天前
WPF Grid 布局高效扩展:GridHelpers 附加属性工具类全解析
wpf
张人玉2 天前
WPF 多语言实现完整笔记(.NET 4.7.2)
笔记·.net·wpf·多语言实现·多语言适配
暖馒2 天前
深度剖析串口通讯(232/485)
开发语言·c#·wpf·智能硬件
我要打打代码3 天前
WPF控件(2)
wpf