根据用户选择在WPF中显示数字的小数位

问题描述 投票:0回答:1

我想在WPF窗口中显示一些double类型的数字。应允许用户选择应显示多少位小数。

我想直接在视图(XAML)中解决这个问题,而不需要格式化后面代码中的数字。我尝试使用 StringFormatMultiBinding:

显示具有选定小数位数的绑定数字

MainWindow.xaml:

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    Width="400"  Height="100">

<StackPanel Orientation="Horizontal" Height="30">

    <TextBlock  Margin="5" >Precision:</TextBlock>
    
    <ComboBox x:Name="cbPrecision" 
                Margin="5" 
                MinWidth="80"
                ItemsSource="{Binding Path=DecimalPlaces}" 
                DisplayMemberPath="Value" 
                SelectedValuePath="Key"/>

    <TextBlock Margin="5" >
        <TextBlock.Text>
            <MultiBinding StringFormat="Number: {0:N{1}}">
                <Binding Path="SomeNumber"/>
                <Binding Path="SelectedValue" ElementName="cbPrecision"/>
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>

</StackPanel>

MainWindow.xaml.cs:

using System.Collections.Generic;
using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
        }

        public Dictionary<int, double> DecimalPlaces { get; } = new() {
            { 0, 1 },
            { 1, 0.1 },
            { 2, 0.01 },
            { 3, 0.001 }
        };

        public double SomeNumber { get; set; } = 123.45678;
    }
}

结果 TextBox 根本不显示:

预期结果:


观察:

“嵌套”字符串格式一定有问题

<MultiBinding StringFormat="Number: {0:N{1}}">

因为将包含 StringFormat 的代码行更改为

<MultiBinding StringFormat="Number: {0:N4}-DecimalPlaces: {1}">

正确显示文本框中的值:

wpf xaml data-binding string-formatting
1个回答
0
投票

首先,将

TextBlock
替换为
Label
,它具有用于绑定的
ContentStringFormat
属性。

然后,定义一个实现

INotifyPropertyChanged
接口的类。

具体实现如下:


// in Window_Loaded
panel.DataContext = new PanelModel();

class PanelModel : INotifyPropertyChanged
{
    public Dictionary<string, double> DecimalPlaces { get; } = new() {
        { "N0", 1 },
        { "N1", 0.1 },
        { "N2", 0.01 },
        { "N3", 0.001 },
        { "N4", 0.0001 }
    };

    string _ContentFormat = "N0";
    double _SomeNumber = 123.45678;

    public string ContentFormat {
        get => _ContentFormat;
        set
        {
            if (value != _ContentFormat)
            {
                _ContentFormat = value;
                OnPropertyChanged(nameof(ContentFormat));
                OnPropertyChanged(nameof(SomeNumber));
            }
        }
    }

    public double SomeNumber
    {
        get => _SomeNumber;
        set
        {
            if (value != _SomeNumber)
            {
                _SomeNumber = value;
                OnPropertyChanged(nameof(SomeNumber));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

我尝试将

comboBox1.SelectedValue
绑定到
ContentStringFormat
,但不起作用。

因此,我使用了

INotifyPropertyChanged
界面,并在
SomeNumber
更改时触发了 ContentFormat
Changed
通知。

<StackPanel x:Name="panel" Orientation="Horizontal">

    <Label Content="Precision: " />

    <ComboBox x:Name="comboBox1"
                ItemsSource="{Binding Path=DecimalPlaces}"
                DisplayMemberPath="Value"
                SelectedValuePath="Key"
                SelectedValue="{Binding Path=ContentFormat}"
                VerticalContentAlignment="Center"
                Width="120"/>

    <TextBox Text="{Binding Path=SomeNumber, UpdateSourceTrigger=PropertyChanged}"
             Width="120"
             Margin="15,0"/>

    <Label x:Name="labelSomeNumber"
            Content="{Binding Path=SomeNumber}"
            ContentStringFormat="{Binding Path=ContentFormat}" />

</StackPanel>
© www.soinside.com 2019 - 2024. All rights reserved.