代码之家  ›  专栏  ›  技术社区  ›  Basssprosse

将IsEnabled属性绑定到模型属性

  •  1
  • Basssprosse  · 技术社区  · 7 年前

    我没有使用mvvm模式。我直接将UI绑定到模型。

    我的问题是与模型属性的绑定有效。如果模型属性 MyStringValue 无效,并且 MyBoolValue -属性也会更改。但我的按钮不会更新IsEnabled属性。

    我的XAML看起来像那样

    <Window x:Class="OkButtonTest.MainWindow"
            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:OkButtonTest"
            mc:Ignorable="d"
            Title="MainWindow">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <TextBox Grid.Row="0" Text="{Binding MyStringValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
            <Button x:Name="MyExampleButton" Grid.Row="1" IsEnabled="{Binding MyBoolValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Click="Button_Click" />
        </Grid>
    </Window>
    

    DataContext在csharp代码处绑定到模型:

    using System.Windows;
    
    namespace OkButtonTest
    {
        public partial class MainWindow : Window
        {
            ModelExample modelExample = new ModelExample();
    
            public MainWindow()
            {
                InitializeComponent();
                DataContext = modelExample;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                MessageBox.Show("Button was clicked");
            }
        }
    }
    

    注意,我已经实现了 Fody.PropertyChanged 在我的模型中,我不需要为每个属性实现PropertyChanged。

    using System;
    using System.ComponentModel;
    
    namespace OkButtonTest
    {
        public class ModelExample : INotifyPropertyChanged, IDataErrorInfo
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            private string myStringValue = "";
            public string MyStringValue
            {
                get
                {
                    return myStringValue;
                }
                set
                {
                    myStringValue = value;
                }
            }
    
            private bool myBoolValue;
            public bool MyBoolValue
            {
                get
                {
                    return myBoolValue;
                }
                set
                {
                    myBoolValue = value;
                    Console.WriteLine($"MyBoolValue is {MyBoolValue.ToString()}");
                }
            }
    
            public string Error
            {
                get
                {
                    if(MyStringValue.Length < 5)
                    {
                        MyBoolValue = false;
                        return "Invalid string value";
                    }
    
                    MyBoolValue = true;
                    return string.Empty;
                }
            }
    
            public string this[string columnName]
            {
                get
                {
                    return Error;
                }
            }
        }
    }
    

    为什么我的按钮不更新?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Janne Matikainen    7 年前

    似乎您应该使用以下语法来允许fody预处理viewmodel的getter和setter。

    [AddINotifyPropertyChangedInterface]
    public class ModelExample : IDataErrorInfo
    {
        ...
    }
    

    还要确保你的FodyWeavers中有这个。xml

    <?xml version="1.0" encoding="utf-8" ?>
    <Weavers>
      <PropertyChanged/>
    </Weavers>
    
        2
  •  1
  •   mm8    7 年前

    仅返回a string Error 属性并设置 MyBoolValue 的setter中的属性 MyStringValue :

    public class ModelExample : INotifyPropertyChanged, IDataErrorInfo
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private string myStringValue = "";
        public string MyStringValue
        {
            get
            {
                return myStringValue;
            }
            set
            {
                myStringValue = value;
                MyBoolValue = !string.IsNullOrEmpty(myStringValue) && myStringValue.Length > 4;
            }
        }
    
        private bool myBoolValue;
        public bool MyBoolValue
        {
            get
            {
                return myBoolValue;
            }
            set
            {
                myBoolValue = value;
            }
        }
    
        public string Error
        {
            get
            {
                if (MyStringValue.Length < 5)
                {
                    return "Invalid string value";
                }
                return string.Empty;
            }
        }
    
        public string this[string columnName]
        {
            get
            {
                return Error;
            }
        }
    }
    

    一个能手不应该做任何事情。您当前设置 MyBoolValue 在getter of the 错误 属性导致 StackoverflowExcpetion 当我运行它时被抛出。