Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在文本框中进行任何更改时立即更改按钮的启用状态?_C#_Wpf_Xaml_Mvvm_Data Binding - Fatal编程技术网

C# 在文本框中进行任何更改时立即更改按钮的启用状态?

C# 在文本框中进行任何更改时立即更改按钮的启用状态?,c#,wpf,xaml,mvvm,data-binding,C#,Wpf,Xaml,Mvvm,Data Binding,我使用数据绑定和命令绑定来设置按钮的启用状态,这取决于特定字符串属性是否具有值。或者您可能会说,我有一个强制文本框,我希望用户在输入至少1个字符之前不能单击“确定” 我的代码正是这样做的,只是在文本框未聚焦之前,按钮的启用状态没有更新,例如按Tab键。我希望在文本框内容发生任何更改时立即发生这种情况。我怎样才能做到这一点?当然,不需要脱离MVVM 查看: <Window x:Class="Gebietsmanager.GebietBearbeitenDlg.View" xm

我使用数据绑定和命令绑定来设置按钮的启用状态,这取决于特定字符串属性是否具有值。或者您可能会说,我有一个强制文本框,我希望用户在输入至少1个字符之前不能单击“确定”

我的代码正是这样做的,只是在文本框未聚焦之前,按钮的启用状态没有更新,例如按Tab键。我希望在文本框内容发生任何更改时立即发生这种情况。我怎样才能做到这一点?当然,不需要脱离MVVM

查看:

<Window x:Class="Gebietsmanager.GebietBearbeitenDlg.View"
        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:Gebietsmanager.GebietBearbeitenDlg"
        mc:Ignorable="d"
        d:DataContext="{d:DesignInstance local:ViewModel}"
        Title="Gebiet bearbeiten" Height="110" Width="300" WindowStartupLocation="CenterOwner" ShowInTaskbar="False" ResizeMode="NoResize">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Label Margin="8,8,0,0">Name:</Label>
        <TextBox Grid.Column="1" Text="{Binding Name}" Margin="8,8,8,0"/>
        <StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal" Margin="8,8,0,0">
            <Button IsDefault="True" Command="{Binding Commit}">Ok</Button>
            <Button Command="{Binding Rollback}" Margin="8,0,0,0">Reset</Button>
            <Button IsCancel="True" Margin="8,0,0,0">Cancel</Button>
        </StackPanel>
    </Grid>
</Window>
using System.ComponentModel;

namespace Gebietsmanager.GebietBearbeitenDlg
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ViewModel(Gebiet gebiet)
        {
            _gebiet = gebiet;
            _gebietCopy = new Gebiet();
            Helpers.CopyPropValues(_gebietCopy, gebiet);

            Commit = new Command(
                () => Helpers.CopyPropValues(_gebiet, _gebietCopy),
                () => !string.IsNullOrEmpty(_gebietCopy.Name));
            Rollback = new Command(DoRollback);
        }

        private readonly Gebiet _gebiet;
        private readonly Gebiet _gebietCopy;

        private void DoRollback()
        {
            Helpers.CopyPropValues(_gebietCopy, _gebiet);
            OnPropertyChanged();
        }

        public string Name
        {
            get { return _gebietCopy.Name; }
            set
            {
                if (_gebietCopy.Name != value)
                {
                    _gebietCopy.Name = value;
                    OnPropertyChanged(nameof(Name));
                }
            }
        }

        public Command Commit { get; private set; }
        public Command Rollback { get; private set; }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
using System;
using System.Windows.Input;

namespace Gebietsmanager
{
    public sealed class Command : ICommand
    {
        public Command(Action executeAction, Func<bool> canExecutePredicate = null)
        {
            _executeAction = executeAction;
            _canExecutePredicate = canExecutePredicate;
        }

        private readonly Action _executeAction;
        private readonly Func<bool> _canExecutePredicate;

        public void Execute(object parameter)
        {
            _executeAction?.Invoke();
        }

        public bool CanExecute(object parameter)
        {
            return _canExecutePredicate?.Invoke() ?? true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }
}
命令执行:

<Window x:Class="Gebietsmanager.GebietBearbeitenDlg.View"
        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:Gebietsmanager.GebietBearbeitenDlg"
        mc:Ignorable="d"
        d:DataContext="{d:DesignInstance local:ViewModel}"
        Title="Gebiet bearbeiten" Height="110" Width="300" WindowStartupLocation="CenterOwner" ShowInTaskbar="False" ResizeMode="NoResize">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Label Margin="8,8,0,0">Name:</Label>
        <TextBox Grid.Column="1" Text="{Binding Name}" Margin="8,8,8,0"/>
        <StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal" Margin="8,8,0,0">
            <Button IsDefault="True" Command="{Binding Commit}">Ok</Button>
            <Button Command="{Binding Rollback}" Margin="8,0,0,0">Reset</Button>
            <Button IsCancel="True" Margin="8,0,0,0">Cancel</Button>
        </StackPanel>
    </Grid>
</Window>
using System.ComponentModel;

namespace Gebietsmanager.GebietBearbeitenDlg
{
    public class ViewModel : INotifyPropertyChanged
    {
        public ViewModel(Gebiet gebiet)
        {
            _gebiet = gebiet;
            _gebietCopy = new Gebiet();
            Helpers.CopyPropValues(_gebietCopy, gebiet);

            Commit = new Command(
                () => Helpers.CopyPropValues(_gebiet, _gebietCopy),
                () => !string.IsNullOrEmpty(_gebietCopy.Name));
            Rollback = new Command(DoRollback);
        }

        private readonly Gebiet _gebiet;
        private readonly Gebiet _gebietCopy;

        private void DoRollback()
        {
            Helpers.CopyPropValues(_gebietCopy, _gebiet);
            OnPropertyChanged();
        }

        public string Name
        {
            get { return _gebietCopy.Name; }
            set
            {
                if (_gebietCopy.Name != value)
                {
                    _gebietCopy.Name = value;
                    OnPropertyChanged(nameof(Name));
                }
            }
        }

        public Command Commit { get; private set; }
        public Command Rollback { get; private set; }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
using System;
using System.Windows.Input;

namespace Gebietsmanager
{
    public sealed class Command : ICommand
    {
        public Command(Action executeAction, Func<bool> canExecutePredicate = null)
        {
            _executeAction = executeAction;
            _canExecutePredicate = canExecutePredicate;
        }

        private readonly Action _executeAction;
        private readonly Func<bool> _canExecutePredicate;

        public void Execute(object parameter)
        {
            _executeAction?.Invoke();
        }

        public bool CanExecute(object parameter)
        {
            return _canExecutePredicate?.Invoke() ?? true;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }
}
使用系统;
使用System.Windows.Input;
命名空间Gebietsmanager
{
公共密封类命令:ICommand
{
公共命令(Action executeAction,Func canExecutePredicate=null)
{
_executeAction=executeAction;
_canExecutePredicate=canExecutePredicate;
}
私有只读操作\u执行;
私有只读功能可执行指令;
public void Execute(对象参数)
{
_executeAction?.Invoke();
}
公共布尔CanExecute(对象参数)
{
返回_canExecutePredicate?.Invoke()?true;
}
公共事件事件处理程序CanExecuteChanged
{
添加{CommandManager.RequerySuggested+=value;}
删除{CommandManager.RequerySuggested-=value;}
}
}
}

您需要在绑定中设置
UpdateSourceTrigger=PropertyChanged

MVVMLight的示例:

XAML


您需要在绑定中设置
UpdateSourceTrigger=PropertyChanged

MVVMLight的示例:

XAML


快速浏览一下,但是你的文本框绑定应该是{binding Name,UpdateSourceTrigger=PropertyChanged}快速浏览一下,但是你的文本框绑定应该是{binding Name,UpdateSourceTrigger=PropertyChanged}我几乎为这个容易回答的问题感到羞愧。我问了之后才发现。只是想确保这里的答案是一样的非常感谢。我几乎为这个容易回答的问题感到羞愧。我问了之后才发现。只是想确保这里的答案是一样的非常感谢。