将对象(未知类型)双向绑定到Slider

时间:2015-03-18 15:00:39

标签: c# wpf

我有一个Slider,它绑定到一个名为MyValue的对象。 MyValue的类型未知。在_currentType中指定了它,无论是整数还是浮点数。

我的ViewModel如下所示:

private Type _currentType;

public object MyValue
{
    get
    {
        if (_myValue != null)
            return _myValue.ToString();
        return null;
    }
    set
    {
        if (_myValue != value)
        {
            _myValue = Convert.ChangeType(value, _currentType);
            OnPropertyChanged("MyValue");
        }
    }
}

和Slider XAML看起来像这样:

<Slider Value="{Binding MyValue, Mode=TwoWay}" />

在上面的代码中,OnPropertyChanged("MyValue")实际上并未更新我的滑块的值。但是,当我使用DispatcherTimer而不是每隔几毫秒调用OnPropertyChanged("MyValue");时,它就能完美地工作。

任何人都可以告诉我为什么它不会与&#34;直接&#34;绑定(我在发布的代码中的方式)?

更新

我真的不认为实际问题是由转换问题引起的。当我使用以下计时器每100毫秒更新一个滑块时,它确实可以正常工作。

private CollectionViewSource _msgListView;
private DispatcherTimer TmrDisplay;

public MyViewModel()
{
    TmrDisplay = new DispatcherTimer();
    TmrDisplay.Tick += TmrDisplay_Tick;
    TmrDisplay.Interval = new TimeSpan(0, 0, 0, 0, 100);
    TmrDisplay.Start();
}

private void TmrDisplay_Tick(object sender, EventArgs e)
{
    if (MsgListView != null)
    {
        foreach (Message msg in MsgListView)
            msg.OnPropertyChangedEvent("MyValue"); // bound to the Slider
    }
}

public ListCollectionView MsgListView
{
    get
    {
        return (ListCollectionView)_msgListView.View;
    }
}

由于我有一个巨大的Collection绑定到一个非常大的ListView(每个项目包含一个Slider ...),当我使用Timer时它太慢了。这就是我试图让它与传统绑定一起工作的原因。但是,由于它适用于计时器(没有实施IValueConverter),我不认为这是实际问题。

此外,我尝试通过以下方式将值转换器绑定到XAML中的Slider。但是,它仍然没有用。

<Slider Value="{Binding MyValue, Converter={StaticResource SliderConverter}, Mode=TwoWay}" />

问题已解决

我从另一个线程(而不是UI线程)调用OnPropertyChanged事件。这就是为什么它没有工作......

1 个答案:

答案 0 :(得分:1)

目标和源属性应该具有相同的类型,否则您需要一个转换器。框架尝试使用默认的(DoubleConverter),但它不适合您的情况。

因此,尝试实现并使用(在绑定中)您自己的转换器:

public class MyValueDoubleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return 0d;
        }

        return System.Convert.ToDouble(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}