1

テキストが 3 つの異なるプロパティにバインドされている 3 つのテキストブロックがあります。

<TextBlock Style="{StaticResource textBlockStyle2}"
           Text="{Binding Path=TWD,
                          Mode=TwoWay,
                          UpdateSourceTrigger=PropertyChanged},
                          StringFormat={}{0:F1} M}" />
<TextBlock Style="{StaticResource textBlockStyle2}"
           Text="{Binding Path=Alt,
                          Mode=TwoWay,
                          UpdateSourceTrigger=PropertyChanged},
                          StringFormat={}{0:F1} M}" />
<TextBlock Style="{StaticResource textBlockStyle2}"
           Text="{Binding Path=Dep,
                          Mode=TwoWay,
                          UpdateSourceTrigger=PropertyChanged},
                          StringFormat={}{0:F1} M}" />

ビューモデルのプロパティは次のとおりです。

private double _TWD;
public double TWD
{
    get { return _TWD; }
    set { _TWD = value; OnPropertyChanged("TWD"); }
}

private double _Alt;
public double Alt
{
    get { return _Alt; }
    set { _Alt = value; OnPropertyChanged("Alt"); }
}

private double _Dep;
public double Dep
{
    get { return _Dep; }
    set { _Dep = value; OnPropertyChanged("Dep"); }
}

現在、これらはメートル単位です。これは、テキストブロックの StringFormat プロパティの 'M' です。私がやろうとしているのは、別のテキストブロック(これはコントロールテンプレートを使用してボタンの内側になります)を(コマンドを介して)「クリック」すると、上記のテキストブロックの値をフィートに変換して追加したいということです値の後に「F」。もう 1 回クリックすると、メートルに戻されます。

に基づいて値を変換しただけのコマンドを追加することを考えていましたbool isMeters。ただし、テキストブロックの値は常に (毎秒) 更新されるため、値が変更されるたびに関数を呼び出す必要はありません。この機能を実現するために私が考えていないより簡単な方法はありますか?

ノート:

1 meter = 3.2808 ft
1ft = 0.3048 meter
4

2 に答える 2

2

<MultiBinding>すべての TextBlock で for each プロパティと共にa を使用できますIMultiValueConverterが、私の意見では、これは XAML 全体を台無しにするだけなので、あまりお勧めしません。

しかし、間違いなくより実行可能な方法は、double プロパティと string プロパティのペアを持つことです。前者は常にメートル単位の生の値です。後者は、ビューに表示される現在の単位を表します。

したがって、ViewModel は次のようになります。

// This is set by the command.
private bool _isMeters = true;

private double _Alt;
public double Alt
{
    get { return _Alt; }
    set { _Alt = value; OnPropertyChanged("Alt"); OnPropertyChanged("AltInCurrentUnit"); }
}
// Rename the suffix as you wish.
public string AltInCurrentUnit => GetInCurrentUnit(_Alt);

// This method is used by all "InCurrentUnit"-properties.
private string GetInCurrentUnit(double meters) =>
    // If you don't like expression bodied methods or ternaries then reformat as you wish.
    _isMeters ?
        $"{meters:F1} M" :
        $"{(meters * 3.2808):F1} F";

そして、あなたのビューは次のようにする必要があります:

<TextBlock Style="{StaticResource textBlockStyle2}" Text="{Binding AltInCurrentUnit}" />

とにかくプロパティが毎秒更新されるPropertyChanged場合、コマンドによって単位が変更された場合、特別な呼び出しは必要ないかもしれません。もちろん、ビューでこの生のプロパティをバインドする必要がなくなっ
た場合は、省略できます。OnPropertyChanged("Alt")

于 2016-12-02T17:43:56.703 に答える
0

コンバーターを使用して動作させました。

public class MetersToFeetConverter : IValueConverter
{
    /// <summary>
    /// Converts meters to feet.
    /// </summary>
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        value = (double)value * 3.2808;
        return (value.ToString() + " F"); 
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

次に、ビューモデルで:

private bool _isMeters = true;
public bool IsMeters
{
    get { return _isMeters; }
    set { _isMeters = value; OnPropertyChanged("IsMeters"); }
}

//called when I click the button to convert
public void ConvertData(object parameter)
{
    if (_isMeters == false)
    {
        IsMeters = true;
    }
    else
    {
        IsMeters = false;
    }
}

次に、テキスト ボックスの xaml バインディングは、データ トリガーを使用して次のようになります。

<Style.Triggers>
    <DataTrigger Binding="{Binding IsMeters, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="False">
        <Setter Property="Text" Value="{Binding Path=TWD, Converter={StaticResource metersToFeetConverter}}" />
    </DataTrigger>
</Style.Triggers>

注:@haindlの回答も機能しましたが、この方法で実行するまで表示されませんでした。

于 2016-12-05T12:30:09.140 に答える