【问题标题】:IValueConverter.Convert doesn't get called on a OneWay bindIValueConverter.Convert 不会在 OneWay 绑定上被调用
【发布时间】:2011-04-06 11:05:57
【问题描述】:

我有一个绑定到我的 XAML 中的 button.IsEnabled 属性的布尔属性(在 setter 中称为 INotifyPropertyChanged)。目前我正在使用TwoWay 绑定,但这会导致问题,我只需要OneWay 绑定。我的问题是我正在使用的转换器在程序第一次启动之后不会被调用。我在设置器中放置了断点,它被称为加载,但Convert() 方法根本没有被调用。这是为什么呢?

一些代码:

public bool IsSaving
    {
        get
        {
            return _isSaving;
        }
        set
        {
            _isSaving = value;
            NotifyOfPropertyChange(() => IsSaving);
        }
    }

和 XAML:

IsEnabled="{Binding Path=IsSaving, Mode=OneWay, Converter={StaticResource booleanToNotEnabledConverter}}"

转换器实际上只是返回!(bool)value,因此当IsSaving 为真时,按钮将被禁用。

【问题讨论】:

  • 它应该可以工作,再次检查所有相关代码。您确定将其更改为 TwoWay 时它可以直接工作吗?
  • 当我使用 TwoWay 时,它总是被调用
  • 你能精简代码并发布代码吗?
  • 这是 Silverlight 还是 WPF?我想在同一个环境下测试一下。
  • 抱歉,这个特殊的项目是 Silverlight。如果可以的话,我会删除 WPF 标记。

标签: c# silverlight data-binding


【解决方案1】:

运行时的某些更改可能会导致绑定中断(因为您绑定到 DataContext + 相对路径),如果您使用 Visual Studio,请务必检查输出窗口是否有任何绑定错误。

编辑:由于没有注明:这是一个标准绑定,贴出的代码也没有问题,所以问题肯定是上下文引起的。

【讨论】:

  • 如果有绑定错误,它肯定不会调用转换器吗?而且,如果出现绑定错误,TwoWay 就不能工作?
  • 不,可以在绑定仍然有效时调用转换器,然后在它破坏绑定之后将完全忽略。这肯定是您所有上下文的问题,因为那段代码没有任何问题。
  • +1 教我绑定错误记录在输出窗口中。
【解决方案2】:

这是我使用的代码,它有效:

转换器:

using System.Windows.Data;
using System;
namespace SilverlightApplication1
{
    public class BooleanToNotEnabledConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return !(bool)value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

XAML:

<UserControl x:Class="SilverlightApplication1.MainPage"
             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:SilverlightApplication1"
             mc:Ignorable="d"
             d:DesignHeight="300"
             d:DesignWidth="400">
    <UserControl.Resources>
        <local:BooleanToNotEnabledConverter x:Key="booleanToNotEnabledConverter" />
    </UserControl.Resources>
    <StackPanel Margin="100">

        <Button Content="Flip"
                Click="Button_Click" />
        <TextBlock Text="{Binding IsSaving}"
                   Height="20" />
        <Button IsEnabled="{Binding IsSaving, Mode=OneWay, Converter={StaticResource booleanToNotEnabledConverter}}"
                Content="Some Button" />
    </StackPanel>
</UserControl>

后面的代码:

using System.Windows.Controls;
using System.Windows;
using System.ComponentModel;
namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        private Data _data;
        public MainPage()
        {
            InitializeComponent();
            _data = new Data { IsSaving = true };
            this.DataContext = _data;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _data.IsSaving = !_data.IsSaving;
        }
    }

    public class Data : INotifyPropertyChanged
    {
        #region IsSaving Property
        private bool _isSaving;
        public bool IsSaving
        {
            get
            {
                return _isSaving;
            }
            set
            {
                if (_isSaving != value)
                {
                    _isSaving = value;
                    OnPropertyChanged("IsSaving");
                }
            }
        }
        #endregion

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            var p = PropertyChanged;
            if (p != null)
            {
                p(this, new PropertyChangedEventArgs(propertyName));

            }
        }
    }
}

【讨论】:

  • 抱歉,你能把你的代码精简到最低限度,这样它仍然包含问题,然后发布吗?当我忘记公开数据类时,我有一些怪癖。就这么简单……
【解决方案3】:

您确定使用正确的字符串调用 PropertyChanged 事件处理程序吗?

PropertyChanged.Invoke(this, new PropertyChangedEventArgs("IsSaving"));

【讨论】:

  • 该属性是从反射中收集的,因此不会拼写错误的属性名称。
  • 您确定 Silverlight 具有使用反射的安全权限吗?你能通过测试我的建议来检查吗?
  • 您可以对公共成员使用反射。
  • 你试过没有反射吗?
猜你喜欢
  • 2011-04-29
  • 2020-01-16
  • 2019-01-22
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
相关资源
最近更新 更多