如何使用ICommand在MVVM中触发TextChanged事件

问题描述 投票:0回答:1

我正在使用2个文本框。如果用户在其中一个文本框中键入内容,则另一个文本框将被禁用。如果用户删除一个文本框中的所有文本,则另一个文本框将重新启用。

这些规则是为了确保只有一个文本框可以包含文本。内部带有文本的文本框是搜索文本框,它侦听搜索按钮触发器“搜索”。

这里是视图的外观:

enter image description here

为了使这些规则起作用,我想根据MVVM标准将TextChanged-Events用作ICommands。我尝试了一下,但是它没有达到我想要的效果。它有什么作用? -如果在“ Artikelbezeichnung”文本框中键入内容,则不会禁用“ Lieferant”文本框;如果删除“ Artikelbezeichnung”内部的所有文本,则“ Lieferant”文本框将被禁用(并且永远不会重新启用)。我相信我无法把握这种奇怪行为的逻辑,这就是为什么我需要您的帮助。我将代码减少到最少,以使您更轻松。

为了使规则生效,我需要更改什么?请看下面的代码,帮帮我。非常感谢您的尝试!

XAML视图

 <StackPanel Height="423" VerticalAlignment="Bottom">
    <Label Name="lblArtikelbezeichnung" Content="Artikelbezeichnung:" Margin="20, 20, 20, 0"></Label>
    <TextBox Name="txtArtikelbezeichnung" 
             Width="Auto" 
             Margin="20, 0, 20, 0"
             IsEnabled="{Binding BezEnabled}"
             Text="{Binding BezText}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="TextChanged">
                <i:InvokeCommandAction Command="{Binding TextChangedBez}" />
            </i:EventTrigger>
            <i:EventTrigger EventName="KeyUp">
                <i:InvokeCommandAction Command="{Binding KeyUpBez}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>
    <!--TextChanged="txtArtikelbezeichnung_TextChanged" 
             KeyUp="txtArtikelbezeichnung_KeyUp"-->
    <Label Name="lblLieferant" Content="Lieferant:" Margin="20, 0, 20, 0"></Label>
    <TextBox Name="txtLieferant" 
             Width="Auto" 
             Margin="20, 0, 20, 0"
             IsEnabled="{Binding LiefEnabled}"
             Text="{Binding LiefText}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="TextChanged">
                <i:InvokeCommandAction Command="{Binding TextChangedLief}" />
            </i:EventTrigger>
            <i:EventTrigger EventName="KeyUp">
                <i:InvokeCommandAction Command="{Binding KeyUpLief}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>
        <!--TextChanged="txtLieferant_TextChanged" 
             KeyUp="txtLieferant_KeyUp"-->
    <Button Name="btnSuchen" 
            Content="Suchen" 
            Width="100" Height="25" 
            Margin="20, 10,240, 10" 
            Command="{Binding GefilterteSuche}">
    </Button>
...
<StackPanel>

背后的代码

 using System.Windows;

namespace Lieferscheine
{
    /// <summary>
    /// Interaktionslogik für artikelHinzu.xaml
    /// </summary>
    public partial class artikelHinzu : Window
    {

        public artikelHinzu()
        {
            InitializeComponent();
            DataContext = new ArtikelHinzuViewModel();
        }     
    }
}

查看模型

public class ArtikelHinzuViewModel : INotifyPropertyChanged
{

    //ICommands
    public ICommand TextChangedLief => new DelegateCommand<object>(TextChangedLieferant);        
    public ICommand TextChangedBez => new DelegateCommand<object>(TextChangedBezeichnung);


    private bool _bezEnabled = true;
    private bool _liefEnabled = true;
    public bool BezEnabled
    {
        get
        {
            return _bezEnabled;
        }
        set
        {
            _bezEnabled = value;
            OnPropertyChanged("BezEnabled");
        }
    }
    public bool LiefEnabled
    {
        get 
        { 
            return _liefEnabled;
        }

        set
        {
            _liefEnabled = value;
            OnPropertyChanged("LiefEnabled");
        }
    }

    private string _bezText;
    private string _liefText;
    public string LiefText
    {
        get
        {
            return _liefText;
        }
        set
        {
            _liefText = value;
            OnPropertyChanged("LiefText");
        }
    }

    public string BezText
    {
        get
        {
            return _bezText;
        }
        set
        {
            _bezText = value;
            OnPropertyChanged("BezText");
        }
    }

    public void TextChangedBezeichnung(object param)
    {
        if (!String.IsNullOrWhiteSpace(BezText))
        {
            LiefEnabled = false;
        }
        else
        {
          LiefEnabled = true;
        }
    }

    public void TextChangedLieferant(object param)
    {
        if (!String.IsNullOrWhiteSpace(LiefText))
        {
           BezEnabled = false;
        }
        else
        {
            BezEnabled = true;
        }
    }
public event PropertyChangedEventHandler PropertyChanged;
    public virtual void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    //Konstruktor
    public ArtikelHinzuViewModel()
    {

    }
}
c# wpf mvvm data-binding icommand
1个回答
1
投票

我相信不良行为是由赛事赛车引起的。

请注意,数据绑定机制by default在绑定目标(UI元素)LostFocus上调用Text属性的设置器。但是在TextBox失去焦点之前已经触发了TextChanged Event。这会导致您的命令无法产生正确的逻辑。

一个快速的解决方法是

Text="{Binding BezText, UpdateSourceTrigger=PropertyChanged}">

当然,我不知道您的确切情况,但是即使在MVVM的意义上,我也不认为有必要使用ICommand和System.Windows.Interactivity。您可以考虑以下内容:

ViewModel

        public string LiefText
        {
            get
            {
                return _liefText;
            }
            set
            {
                _liefText = value;
                OnPropertyChanged("LiefText");

                if (!String.IsNullOrWhiteSpace(_liefText))
                    BezEnabled = false;
                else
                    BezEnabled = true;
            }
        }

        public string BezText
        {
            get
            {
                return _bezText;
            }
            set
            {
                _bezText = value;
                OnPropertyChanged("BezText");

                if (!String.IsNullOrWhiteSpace(_bezText))
                    LiefEnabled = false;
                else
                    LiefEnabled = true;
            }
        }

查看

        <TextBox Name="txtArtikelbezeichnung" 
             Width="Auto" 
             Margin="20, 0, 20, 0"
             IsEnabled="{Binding BezEnabled}"
             Text="{Binding BezText, UpdateSourceTrigger=PropertyChanged}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="KeyUp">
                    <i:InvokeCommandAction Command="{Binding KeyUpBez}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>

       <TextBox Name="txtLieferant" 
             Width="Auto" 
             Margin="20, 0, 20, 0"
             IsEnabled="{Binding LiefEnabled}"
             Text="{Binding LiefText, UpdateSourceTrigger=PropertyChanged}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="KeyUp">
                    <i:InvokeCommandAction Command="{Binding KeyUpLief}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>
© www.soinside.com 2019 - 2024. All rights reserved.