一个控件上的属性更改以刷新另一个转换器?

时间:2013-05-22 09:50:43

标签: c# wpf xaml

当用户输入他们的体重时,我有一个页面。数据始终存储为lbs,因为我在应用程序中的大部分计算都是基于lbs。但是,视觉上用户可以输入kg,lbs和stone。

因此,对于我的问题的例子,我们可以说我们有以下类。

int UnitType
double Weight

现在,让我们说我有一个页面,其中有一个ComboBox,其SelectedIndex绑定到UnitType。 ComboBox有3个项目“lbs”,“kg”和“st”。在那下面有一个文本框,你可以输入一个值。这将绑定到Weight并将有一个转换器。

假设用户选择“lbs”并输入200,但随后决定从lbs更改为kg。我的问题是如何获取ComboBox的部分更改事件以触发文本框转换器的刷新?

在我脑海里,我猜我必须做这样的事情

private int _unitType;
public int UnitType
{
   get { return _unitType;}
   set 
   { 
     _unitType = value;
     NotifyPropertyChanged("UnitType");
     NotifyPropertyChanged("Weight");
   }
 }

private double _weight;
public double Weight
{
   get { return _weight;}
   set 
   { 
     _weight= value;
     NotifyPropertyChanged("Weight");
   }
 }

这是否有用或者我还能做些什么,也许是在绑定本身?

2 个答案:

答案 0 :(得分:2)

您可以实现此目的的一种可能方式如下:
一个。这里我们使用因子变量来存储权重的相对值。我们将相对值存储在构造函数中。
湾1磅= 0.453592 Kg = 0.0714286f Stone。
℃。权重的转换在选定的权重类型

中完成了set属性
            private WeightType _selectedWeightType;
            public WeightType SelectedWeightType
            {
                get { return _selectedWeightType; }
                set
                {
                    var previousType = _selectedWeightType;
                    _selectedWeightType = value;
                    NotifyPropertyChanged("SelectedWeightType");
                    if(previousType != null)
                        CurrentWeight = (CurrentWeight / previousType.Factor) * _selectedWeightType.Factor;
                }
            }

完整的代码如下:
XAML:

<Window x:Class="TestWPFApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestWPFApp"
        Title="MainWindow" Height="350" Width="525">

    <Grid>
        <StackPanel Orientation="Vertical" VerticalAlignment="Center">
            <ComboBox Width="100" Height="20" ItemsSource="{Binding WeightTypeList}" DisplayMemberPath="UnitType" SelectedIndex="0" SelectedItem="{Binding SelectedWeightType}">
            </ComboBox>
            <TextBox Width="100" Height="20" Text="{Binding CurrentWeight,Mode=TwoWay}"></TextBox>
        </StackPanel>
    </Grid>
</Window>

代码背后:

using System.Windows;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System;
using System.ComponentModel;
using System.Windows.Data;
using System.Globalization;
namespace TestWPFApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainViewModel();
        }
    }

    public class WeightType : INotifyPropertyChanged
    {
        private int _id;
        public int Id
        {
            get { return _id; }
            set
            {
                _id = value;
                NotifyPropertyChanged("Id");
            }
        }

        private string _unitType;
        public string UnitType
        {
            get { return _unitType; }
            set
            {
                _unitType = value;
                NotifyPropertyChanged("UnitType");
            }
        }

        private float _factor;
        public float Factor
        {
            get { return _factor; }
            set
            {
                _factor = value;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// Call this to force the UI to refresh it's bindings.
        /// </summary>
        /// <param name="name"></param>
        public void NotifyPropertyChanged(String name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }

    public class MainViewModel : INotifyPropertyChanged
    {
        private List<WeightType> _weightTypeList = new List<WeightType>();
        public List<WeightType> WeightTypeList
        {
            get { return _weightTypeList; }
            set
            {
                _weightTypeList = value;
            }
        }
        private double _currentWeight;
        public double CurrentWeight
        {

            get { return _currentWeight; }
            set
            {
                _currentWeight = value;
                NotifyPropertyChanged("CurrentWeight");
            }
        }

        private WeightType _selectedWeightType;
        public WeightType SelectedWeightType
        {
            get { return _selectedWeightType; }
            set
            {
                var previousType = _selectedWeightType;
                _selectedWeightType = value;
                NotifyPropertyChanged("SelectedWeightType");
                if(previousType != null)
                    CurrentWeight = (CurrentWeight / previousType.Factor) * _selectedWeightType.Factor;
            }
        }

        public MainViewModel()
        {
            WeightTypeList.Add(new WeightType() { Id = 1, UnitType = "Lbs", Factor = 1f });
            WeightTypeList.Add(new WeightType() { Id = 2, UnitType = "Kg",Factor = 0.453592f });
            WeightTypeList.Add(new WeightType() { Id = 1, UnitType = "St", Factor = 0.0714286f });
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(String name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }

    public class BoolToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            return null;
        }

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

}

答案 1 :(得分:1)

  • 您可以拥有计算属性,该属性知道如何转换并显示所选系统中的权重。您可以在两组UnitType和Weight上调用NotifyPropertyChanged(“CalculatedWeight”)。

  • 或者,我会用你的方法。在Weight属性的绑定中有一个转换器并将逻辑放在那里。

  • 更好的选择是创建一个具有组合框和文本框的用户控件,创建一个类“WeightProvider”并将userControl datacontext绑定到该类,然后你有两个选择:

    1. 该类具有计算属性
    2. 用户控件具有转换器本身
    3. 如果你想拥有更多有权重的网页,这是最有效的方式。