【问题标题】:TextBox not triggering PropertyChanged event文本框未触发 PropertyChanged 事件
【发布时间】:2015-12-14 17:39:25
【问题描述】:

我正在努力弄清楚为什么当我在文本框中输入文本并离开控件时没有触发 propertychanged 事件或 lostfocus 事件。

我正在构建一个通用 Windows 平台应用程序。

我知道我在做一些迟钝的事情,但我只是没有看到。

有什么建议吗?

XAML:

<Page
    x:Class="xxx.Client.FormPage"
    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:viewModels="using:xxx.xxx.ViewModels"
    Background="LightBlue"
    mc:Ignorable="d">

    <Page.Resources>
        <Style x:Key="TextBoxStyle" TargetType="TextBox">
            <Setter Property="HorizontalAlignment" Value="Stretch" />
            <Setter Property="TextAlignment" Value="Center" />
        </Style>
    </Page.Resources>

    <Page.DataContext>
        <viewModels:FormViewModel />
    </Page.DataContext>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>

        <TextBox Grid.Row="0" Text="{Binding InstructorNameInput}" Style="{StaticResource TextBoxStyle}" 
                 PlaceholderText="Instructor Name" />

        <TextBox Grid.Row="1" Text="{Binding InstructorIdInput}" Style="{StaticResource TextBoxStyle}"
                 PlaceholderText="Instructor Id" />

        <TextBox Grid.Row="2" Text="{Binding CourseInput}" Style="{StaticResource TextBoxStyle}"
                 PlaceholderText="Course" />

        <Button Grid.Row="4" Content="Accept" Command="{Binding Submit}" 
                HorizontalAlignment="Stretch"
                Foreground="Black" />
    </Grid>
</Page>

视图模型:

public partial class FormViewModel : ViewModelBase
    {
        public FormViewModel()
        {
            InstructorName = new RequiredField("Instructor's Name:");
            InstructorId = new RequiredField("Instructor's Employee#:");
            Course = new RequiredField("Course:");

            var courses = CourseFactory.Produce();
            var administration = new Administration(courses, null);
            Submit = new DelegateCommand(_=> OnSubmit(), CanSubmit);
        }

        string _instructorNameInput = null;
        public string InstructorNameInput
        {
            get { return _instructorNameInput; }
            set
            {
                if (_instructorNameInput != value)
                {
                    _instructorNameInput = value;
                    OnNotifyPropertyChanged();
                }
            }
        }

        string instructorIdInput = null;
        public string InstructorIdInput
        {
            get { return instructorIdInput; }
            set
            {
                if (instructorIdInput != value)
                {
                    instructorIdInput = value;
                    OnNotifyPropertyChanged();
                }
            }
        }

        string courseInput = null;
        public string CourseInput
        {
            get { return courseInput; }
            set
            {
                if (courseInput != value)
                {
                    courseInput = value;
                    OnNotifyPropertyChanged();
                }
            }
        }

        public RequiredField InstructorName { get; }
        public RequiredField InstructorId { get; }
        public RequiredField Course { get; }

        public ObservableCollection<RequiredField> RequiredFields { get; } = new ObservableCollection<RequiredField>();
    }

ViewModel.internal:

public partial class FormViewModel
    {
        static void OnSubmit()
        {
            var adminsistration = new Administration();
        }

        bool CanSubmit(object obj) => !GetUnsatisfied().Any();

        IEnumerable<RequiredField> GetUnsatisfied()
        {
            if (string.IsNullOrEmpty(InstructorIdInput))
            {
                RequiredFields.Add(InstructorId);
            }
            else
            {
                var result = 0;
                var isNumeric = int.TryParse(InstructorIdInput, out result);

                if (!isNumeric)
                {
                    RequiredFields.Add(new RequiredField(InstructorId.About, "Instructor ID must be numeric"));
                }
            }

            if (string.IsNullOrEmpty(InstructorNameInput))
            {
                RequiredFields.Add(InstructorName);
            }

            if (string.IsNullOrEmpty(CourseInput))
            {
                RequiredFields.Add(Course);
            }

            return RequiredFields;
        }
    }

【问题讨论】:

  • 我不确定 - 您是否缺少 TwoWay 绑定?您希望您的 TextBox 在编辑后设置属性?
  • 我认为 TwoWay 绑定是 TextBoxes 的默认设置?
  • 它没有触发,因为你没有告诉它。在您的 XAML 或 C# 中,您没有引用 LostFocus。如果您 Tab 进出文本框,则没有任何变化,因此您的属性 Setters 中不会触发任何内容。
  • @Romasz 请提供您的评论作为答案。显式设置 TwoWay-binding 解决了我的问题。
  • @ScottNimrod - 以供将来参考,请考虑您提出问题的方式。“当我在文本框中输入文本并离开控件时,没有触发事件。” ...事件与双向绑定不是同一个问题。存在双向绑定,因此可以在绑定源更改时更新 CONTROL。两种完全不同的东西。

标签: xaml winrt-xaml win-universal-app


【解决方案1】:

UWP的默认绑定模式as MSDN says:

默认为 OneWay。

将其设置为 TwoWay

<TextBox Grid.Row="0" Text="{Binding InstructorNameInput, Mode=TwoWay}" .../>

【讨论】:

    猜你喜欢
    • 2021-11-27
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多