我是 C#、WPF、XAML 和 Binding 的新手,為了學習這個不錯的環境,我自己創建了這個小練習:我想顯示一個包含增值稅和不含增值稅的價格。但是我希望在我更改一個欄位后立即自動更新另一個欄位(所以只要我點擊 Tab)。我已經創建了一個類(感謝幫助我在 Stack Overflow 中發布的另一個問題)來進行數學計算。但是我現在向我們發出問題,因為這些欄位沒有更新。我使用 INotifyPropertyChange 介面,但由于某種原因,它不起作用。這是正在發生的事情:

我使用以下 XAML 代碼:
<Window x:Class="BTWv2.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"
xmlns:local="clr-namespace:BTWv2"
mc:Ignorable="d"
Title="MainWindow" Height="150" Width="250">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Label Grid.Column="1" Grid.Row="1" Content="Amount inc VAT:" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBox
Grid.Column="2" Grid.Row="1"
VerticalAlignment="Center" HorizontalAlignment="Center"
Width="100" Text="{Binding IncludeVat,Mode=TwoWay}"/>
<Label Grid.Column="1" Grid.Row="3" Content="Amount excl VAT:" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBox Text="{Binding ExcludeVat,Mode=TwoWay}"
Grid.Column="2" Grid.Row="3"
VerticalAlignment="Center" HorizontalAlignment="Center"
MinWidth="100"
/>
</Grid>
</Window>
這是實際的 C# 代碼(我使用名為 CalculateVAT 的類來計算數字:
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
namespace BTWv2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
CalculateVAT Price = new CalculateVAT();
Price.IncludeVat = 100;
DataContext = Price;
}
public class CalculateVAT : INotifyPropertyChanged
{
private decimal m_IncludeVat; // <- decimal is a better choice for finance
// To compute VAT we should know the percent; let it be known
public const decimal Percent = 21.0m;
public decimal IncludeVat
{
get => m_IncludeVat;
set
{
// negative cash are usually invalid; if it's not the case, drop this check
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value));
m_IncludeVat = value;
Tax = Math.Round(m_IncludeVat / 100 * Percent, 2);
NotifyPropertyChanged();
}
}
public decimal ExcludeVat
{
get => m_IncludeVat - Tax;
set
{
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value));
m_IncludeVat = Math.Round(value / 100 * (100 Percent), 2);
Tax = m_IncludeVat - value;
NotifyPropertyChanged();
}
}
// Let's be nice and provide Tax value as well as IncludeVat, ExcludeVat
public decimal Tax { get; private set; }
public override string ToString() =>
$"Include: {IncludeVat:f2}; exclude: {ExcludeVat:f2} (tax: {Tax:f2})";
public event PropertyChangedEventHandler? PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Has anyone an idea what I'm missing here? I already tried the UpdateSourceTrigger=PropertyChanged setting in the binding, but that doesn't seem to change anything..
uj5u.com熱心網友回復:
假設您想在從 UI 更改 IncludeVat 時更新 ExcludeVat。您將需要為 IncludeVat 的 setter 中的兩個屬性提升通知屬性。
public decimal IncludeVat
{
get => m_IncludeVat;
set
{
// negative cash are usually invalid; if it's not the case, drop this check
if (value < 0)
throw new ArgumentOutOfRangeException(nameof(value));
m_IncludeVat = value;
Tax = Math.Round(m_IncludeVat / 100 * Percent, 2);
NotifyPropertyChanged(nameof(IncludeVat));
NotifyPropertyChanged(nameof(ExcludeVat));
}
}
這將做的是,當您從 UI 更改 IncludeVat 時,setter 現在會引發為 ExcludeVat 更改的屬性。UI 將嘗試通過呼叫 ExcludeVat 的 getter 進行更新。您獲得 ExcludeVat :get => m_IncludeVat - Tax; 現在將獲得更新的值,UI 將反映該值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/336612.html
下一篇:將標簽大小調整為換行文本
