2

テストプロジェクトとして温度コンバーターに取り組んでいます。相互に通信する必要がある 3 つのアップ/ダウン コントロールがあります。(右側のラベルはデバッグ専用です。) 回転させて温度を変更すると (摂氏など)、対応するラベルが正しく更新されますが、ケルビンと華氏の値も同時に変更する必要があります。しかし、そうではありません。なぜだめですか?

その意図は、モデル (TempModel) が 1 つの値 (ケルビン) のみを保持することです。その他は必要に応じて計算する必要があります。摂氏と華氏の値を取得するために、さまざまな方法を試しました。この場合、プライベート _Kelvin 変数から値を計算するモデルにプロパティがあります。起動時には機能しますが、実行時に値を変更しているときは機能しません。

ビューモデルのプロパティでも同様のことを試みました。

解決策はかなり単純で、バインディングと関係があると思いますが、まだ見つかりません。

これはどのように見えるかです: ユーザーインターフェース画像

ビューの XAML コードは次のとおりです。

<Window x:Class="Temperature.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
    Title="Temperature converter" Height="183" Width="468">
<Grid VerticalAlignment="Stretch">
    <Label Content="Kelvin" Height="28" HorizontalAlignment="Left" Margin="10,10,0,0" Name="label1" VerticalAlignment="Top" />
    <extToolkit:DoubleUpDown Name="_KelvinUD" Increment="0.1" FormatString="F2" Value="{Binding Kelvin}" HorizontalAlignment="Left" Width="100" VerticalAlignment="Top" Margin="113,14,0,0" />
    <Label Height="28" HorizontalAlignment="Left" Margin="279,10,0,0" Name="label4" VerticalAlignment="Top" Content="{Binding Kelvin}" />

    <Label Content="Celsius" Height="28" HorizontalAlignment="Left" Margin="12,44,0,0" Name="label2" VerticalAlignment="Top" />
    <extToolkit:DoubleUpDown Name="_CelsiusUD" Increment="0.1" FormatString="F2" Value="{Binding Celsius}" HorizontalAlignment="Left" Width="100" VerticalAlignment="Top" Margin="113,48,0,0" />
    <Label Height="28" HorizontalAlignment="Left" Margin="279,44,0,0" Name="label5" VerticalAlignment="Top" Content="{Binding Celsius}" />

    <Label Content="Fahrenheit" Height="28" HorizontalAlignment="Left" Margin="12,78,0,0" Name="label3" VerticalAlignment="Top" />
    <extToolkit:DoubleUpDown Name="_FarenheitUD" Increment="0.1" FormatString="F2" Value="{Binding Fahrenheit}" HorizontalAlignment="Left" Width="100" VerticalAlignment="Top" Margin="113,82,0,0" />
    <Label Height="28" HorizontalAlignment="Left" Margin="279,78,0,0" Name="label6" VerticalAlignment="Top" Content="{Binding Fahrenheit}" />
</Grid>

背後にあるコード:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Temperature
{
    public partial class MainWindow : Window
    {
        private TempViewModel _viewModel = new TempViewModel();
        TempViewModel ViewModel
        {
            get { return _viewModel; }
        }

        public MainWindow()
        {
            InitializeComponent();
            base.DataContext = ViewModel;
        }
    }
}

モデル:

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace Temperature
{
    public class TempModel
    {
        private double _kelvin;
        public double Kelvin
        {
            get
            {
                return _kelvin;
            }
            set
            {
                _kelvin = value;
                OnPropertyChanged("Kelvin");
            }
        }

        public double Celsius
        {
            get
            {
                return _kelvin - 273.15;
            }
            set
            {
                _kelvin = value + 273.15;
                OnPropertyChanged("Celsius");
            }
        }

        public double Fahrenheit
        {
            get
            {
                return 9.0 / 5.0 * (_kelvin - 273.15) + 32;
            }
            set
            { 
                _kelvin = 5.0 / 9.0 * (value - 32) + 273.15;
                OnPropertyChanged("Fahrenheit");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }
}

ビュー モデル:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Temperature
{
    class TempViewModel
    {
        TempModel _tempModel;

        public TempViewModel()
        {
            _tempModel = new TempModel 
            {
                Kelvin = 300.15 // Initial value
            };
        }

        public TempModel TempModel
        {
            get
            {
                return _tempModel;
            }
            set
            {
                _tempModel = value;
            }
        }

        public double Kelvin
        {
            get
            {
                return _tempModel.Kelvin;
            }
            set
            {
                _tempModel.Kelvin = value;
            }
        }
        public double Celsius
        {
            get
            {
                return _tempModel.Celsius;
            }
            set
            {
                _tempModel.Celsius = value;
            }
        }
        public double Fahrenheit
        {
            get
            {
                return _tempModel.Fahrenheit;
            }
            set
            {
                _tempModel.Fahrenheit = value;
            }
        }

    }
}
4

2 に答える 2

1

1 つのプロパティの変更によって他の 2 つのプロパティも変更される場合は、他のプロパティもビューに通知するために OnPropertyChanged を発生させる必要があります。

これはうまくいくはずです(迅速で汚いアプローチ)。モデルのプロパティを公開してバインドするだけです。

public class TempModel
{
    private double _kelvin;
    public double Kelvin
    {
        get
        {
            return _kelvin;
        }
        set
        {
            _kelvin = value;
            OnPropertyChanged("Kelvin");
            OnPropertyChanged("Celsius");
            OnPropertyChanged("Fahrenheit");
        }
    }

    public double Celsius
    {
        get
        {
            return _kelvin - 273.15;
        }
        set
        {
            _kelvin = value + 273.15;
            OnPropertyChanged("Celsius");
            OnPropertyChanged("Kelvin");
            OnPropertyChanged("Fahrenheit");
        }
    }

    public double Fahrenheit
    {
        get
        {
            return 9.0 / 5.0 * (_kelvin - 273.15) + 32;
        }
        set
        { 
            _kelvin = 5.0 / 9.0 * (value - 32) + 273.15;
            OnPropertyChanged("Fahrenheit");
            OnPropertyChanged("Celsius");
            OnPropertyChanged("Kelvin");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

public class TempViewModel
{
    TempModel _tempModel;

    public TempViewModel()
    {
        _tempModel = new TempModel 
        {
            Kelvin = 300.15 // Initial value
        };
    }

    public TempModel TempModel
    {
        get
        {
            return _tempModel;
        }
        set
        {
            _tempModel = value;
        }
    }
}


<Grid VerticalAlignment="Stretch">

<extToolkit:DoubleUpDown Increment="0.1" FormatString="F2" Value="{Binding TempModel.Kelvin}" HorizontalAlignment="Left" Width="100" VerticalAlignment="Top" Margin="113,14,0,0" />

<extToolkit:DoubleUpDown  Increment="0.1" FormatString="F2" Value="{Binding TempModel.Celsius}" HorizontalAlignment="Left" Width="100" VerticalAlignment="Top" Margin="113,48,0,0" />

<extToolkit:DoubleUpDown  Increment="0.1" FormatString="F2" Value="{Binding TempModel.Fahrenheit}" HorizontalAlignment="Left" Width="100" VerticalAlignment="Top" Margin="113,82,0,0" />
</Grid> 
于 2012-10-26T09:59:42.323 に答える