【问题标题】:Update databinding when using MethodToValueConverter使用 MethodToValueConverter 时更新数据绑定
【发布时间】:2014-11-17 19:43:37
【问题描述】:

我有一个在this 答案中使用MethodToValueConverter 的数据绑定。这很好用,但是在方法的结果发生变化后我很难强制更新视图。这有点难以解释,所以希望一些代码片段会有所帮助。

类对象

[DataContract]
public class RetentionBankItem : INotifyPropertyChanged
{
    #region Private Properties
    public event PropertyChangedEventHandler PropertyChanged;
    private float _rbRevisedRateLoad;
    private float _rbCurrentRateLoad;
    #endregion

    [DataMember]
    public float rbRevisedRateLoad
    {
        get
        {
            return _rbRevisedRateLoad;
        }
        set
        {
            PropertyChanged.ChangeAndNotify(ref _rbRevisedRateLoad, value, () => rbRevisedRateLoad);
            OnPropertyChanged("RateLoadDifference");
        }
    }

    [DataMember]
    public float rbCurrentRateLoad
    {
        get
        {
            return _rbCurrentRateLoad;
        }
        set
        {
            PropertyChanged.ChangeAndNotify(ref _rbCurrentRateLoad, value, () => rbCurrentRateLoad);
            OnPropertyChanged("RateLoadDifference");
        }
    }

    public float RateLoadDifference()
    {
        if (rbCurrentRateLoad != 0)
        {
            return rbRevisedRateLoad / rbCurrentRateLoad;
        }
        return 0;
    }
}

需要注意的是,在下面的代码中,RetentionBank的类型是List<RetentionBankItem>

我的绑定看起来像这样:

<ItemsControl ItemsSource="{Binding RetentionBank}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding rbRevisedRateLoad, Mode=TwoWay}"
                     Grid.Row="2"
                     Grid.Column="0" />

            <TextBox Text="{Binding rbCurrentRateLoad, Mode=TwoWay}"
                     Grid.Row="2"
                     Grid.Column="1" />

            <TextBox Text="{Binding Path=., Converter={StaticResource ConverterMethodToValue}, ConverterParameter='RateLoadDifference', Mode=OneWay}"
                     Grid.Row="2"
                     Grid.Column="2" />
         </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

当前和修订的速率负载已正确设置,但在设置后,RateLoadDifference 永远不会被调用更新。我想需要调用类对象本身来更新,因为这是文本框实际绑定的内容(不一定是方法本身),但我不确定如何做到这一点,或者它是否是正确的方法它。任何帮助或建议将不胜感激。谢谢!

【问题讨论】:

  • 什么是 PropertyChanged.ChangeAndNotify?
  • 它本质上是一种调用OnPropertyChanged 的更简洁(并且由于不使用字符串而对代码更友好)的方式。我从here得到那段代码
  • 它是否以常规方式工作 - _rbCurrentRateLoad = value; OnPropertyChanged()?
  • 很遗憾没有。当前和修订的速率负载属性设置没有问题,但设置后视图不会使用来自RateLoadDifference的最新结果进行更新
  • 您可能需要一个用于 RateLoadDifference 的吸气剂吗?

标签: c# wpf xaml mvvm data-binding


【解决方案1】:

将 RateLoadDifference 更改为属性:

public float RateLoadDifference
{
    get
    {
        if (rbCurrentRateLoad != 0)
        {
            return rbRevisedRateLoad / rbCurrentRateLoad;
        }

        return 0;
    }
}

然后将绑定改为

Binding="{Binding Path=RateLoadDifference, Mode=OneWay}"

【讨论】:

  • 虽然这是一个选项,但我尽量避免以这种方式使用属性。不幸的是,它并不完全适合Choosing Between Properties and Methods 文章中提到的一类。在这种特殊情况下,我会说属性不会造成太大伤害,但在其他情况下,我可能会遇到同样的问题,而我绝对不想放入属性中。
  • 这就是我来这里的原因,看看我是不是有点狭隘,或者是否有办法在不使用属性的情况下做到这一点。我们会看到的!
  • 我认为 ViewModel 功能有时可能是主观的。我编码的方式是将 ViewModel 视为针对特定 View 要求操作模型数据。由于 View 需要 RateLoadDifference,在这种情况下我没有发现问题。 @jmgardn2 会有什么不同?
  • 一般来说,编写比仅仅遵循一个想法所需的更多代码的想法是代码异味 - 转换器很昂贵,在这种情况下可以避免,因此这是一种代码异味。跨度>
  • 更不用说转换器有一定的性能损失,最终应该是一个非常简单的绑定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多