在WPF中绑定按钮的IsEnabled属性

5

我有一个需要在程序中启用/禁用的按钮,我想使用bool的绑定来实现。以下是Button XAML代码:

<Button x:Name="logInButton" Height="30" IsEnabled="{Binding IsLoggedIn}">
                            <Image Source="/images/img.png"></Image>
                        </Button>

以下是被调用的代码:

        public MainWindow()
        {
            InitializeComponent();
            enabled = false;
        }
        private bool enabled;
        public bool IsLoggedIn
        {
            get
            {
                return enabled;
            }
            set
            {
                enabled = value;
            }
        } 

属性IsLoggedIn的值被正确地赋值了。但是IsEnabled没有被赋予我需要的值。例如:
For example 我尝试使用Binding PathBinding Source来设置值,但什么都不起作用。
请指导可能出了什么问题。

除非您将数据上下文分配给控件,否则“IsLoggedIn”必须是视图模型中的属性,而不是视图代码后面的内容(如果您的数据上下文是视图,则现在请恢复它...) - Adriano Repetti
1
如果在GUI加载后更改IsLoggedIn,则需要让WPF系统知道该值已更改。可以将IsLoggedIn声明为DependencyProperty,或者实现INotifyPropertyChanged - Freggar
2个回答

8
然后...我认为一定是这样的。
class Model : INotifyPropertyChanged
    {
        public bool enabled;
        public bool IsLoggedIn
        {
            get
            {
                return enabled;
            }
            set
            {
                enabled = value;
                OnPropertyChanged("IsLoggedIn");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName]string property = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

1
将 Model 的一个实例指派给 MainWindow 的 DataContext 属性。例如,在 MainWindow 构造函数中添加一个类似于 private Model viewModel = new Model(); 的字段,然后添加 DataContext = viewModel; - Clemens
嗯,它应该可以工作。将“enabled”字段设为私有,以避免意外从Model类外部访问它。 - Clemens
@Clemens,谢谢,当我设置IsEnabled="{Binding Path=IsLoggedIn}"时,它确实有帮助,但对于另一个按钮,IsEnabled="{Binding Path=!IsLoggedIn}"不起作用,该按钮应该具有与登录按钮相反的属性。 - Hanna Bilous
2
!IsLoggedIn 不是 WPF 数据绑定中的有效属性路径。请添加另一个属性,或编写一个绑定转换器来反转布尔值。 - Clemens
2
因为这个视图模型几乎就是这样做的,所以我点了赞。顺便说一下,CallerMemberName属性意味着你可以在这里只写OnPropertyChanged()。对于反转,你最好遵循Clemens的建议并创建一个值转换器。你可能需要再次反转布尔值(至少这是我的经验)。 - Mikkel K.

5

缺少两件事:

  1. IsLoggedIn 属性应该在 DataContext 对象中。在 MVVM 中,这意味着它应该在视图模型中。
  2. DataContext 应该实现 INotifyPropertyChanged 接口,这样当您通过编程更新属性时,视图可以发生变化。

我现在无法承诺给您一个更长的答案,这里正在发生一些事情。 - Mikkel K.
OP已经基本回答了这个问题,我想我会点赞那个回答。 - Mikkel K.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接