我想在WPF窗口中显示一些double类型的数字。应允许用户选择应显示多少位小数。
我想直接在视图(XAML)中解决这个问题,而不需要格式化后面代码中的数字。我尝试使用 StringFormat 和 MultiBinding:
显示具有选定小数位数的绑定数字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}">
正确显示文本框中的值:
首先,将
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>