You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从ViewModel访问、修改按钮内容并根据状态执行对应命令

解决方案

MVVM架构下不建议ViewModel直接访问视图层的按钮控件,通过属性绑定即可实现按钮文本的动态切换,具体实现如下:


步骤1:改造基础ViewModel类

首先让ViewModel实现INotifyPropertyChanged接口,新增连接状态、按钮文本两个可通知绑定属性,同时修复原有代码中局部变量覆盖类成员client的问题:

using System.ComponentModel;
using System.Net.Sockets;
using System.Windows;

namespace firstApp
{
    public class ViewModel : INotifyPropertyChanged
    {
        public TcpClient client = null;
        public ICommand MyCommand { get; set; }

        // 新增连接状态属性
        private bool _isConnected;
        public bool IsConnected
        {
            get => _isConnected;
            set
            {
                _isConnected = value;
                OnPropertyChanged(nameof(IsConnected));
                // 状态变更时同步修改按钮文本
                ConnectButtonText = _isConnected ? "Disconnect" : "Connect";
            }
        }

        // 新增按钮文本绑定属性
        private string _connectButtonText = "Connect";
        public string ConnectButtonText
        {
            get => _connectButtonText;
            set
            {
                _connectButtonText = value;
                OnPropertyChanged(nameof(ConnectButtonText));
            }
        }

        public ViewModel()
        {
            MyCommand = new Command(ExecuteMethod, canExecuteMethod);
        }

        private bool canExecuteMethod(object parameter)
        {
            return true;
        }

        public void ExecuteMethod(object parameter)
        {
            try
            {
                Int32 port = 8000;
                if (!IsConnected)
                {
                    // 移除局部变量声明,直接给类成员client赋值
                    client = new TcpClient("127.0.0.1", port);
                    IsConnected = true;
                }
                else
                {
                    client.Close();
                    IsConnected = false;
                }
            }
            catch (ArgumentNullException ex)
            {
                MessageBox.Show(ex.Message);
            }
            catch (SocketException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        // 实现属性变更通知
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

步骤2:修正SendViewModel逻辑

原有SendViewModel构造函数错误绑定了MyCommand,需要修正为绑定MySendCommand:

namespace firstApp
{
    public class SendViewModel: ViewModel
    {
        public ICommand MySendCommand { get; set; }

        public SendViewModel()
        {
            // 修正命令绑定
            MySendCommand = new Command(ExecuteSendMethod, canExecuteMethod);
        }

        private bool canExecuteMethod(object parameter)
        {
            return IsConnected;
        }

        public void ExecuteSendMethod(object parameter)
        {
            if (IsConnected)
            {
                Byte[] data = System.Text.Encoding.ASCII.GetBytes("hello");
                NetworkStream stream = client.GetStream();
                stream.Write(data, 0, data.Length);
            }
            else
            {
                MessageBox.Show("There is no connection");
            }
        }
    }
}

步骤3:XAML绑定配置

直接将按钮的Content属性绑定到ViewModel的ConnectButtonText即可,无需手动操作控件:

<Button Content="{Binding ConnectButtonText}" Command="{Binding MyCommand}"/>
<!-- 发送按钮绑定示例 -->
<Button Content="发送" Command="{Binding MySendCommand}"/>

点击按钮后Command执行逻辑会自动修改ConnectButtonText的值,视图会自动同步更新按钮显示内容。


内容的提问来源于stack exchange,提问作者grif_noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 10:45:03