Skip to content

Commit 819010c

Browse files
Rudy HuynCopilot
andcommitted
Migrate ViewModels to CommunityToolkit.MVVM and wire UnitConverter to native engine
## CommunityToolkit.MVVM Migration - Add CommunityToolkit.Mvvm 8.4.2, set LangVersion 13.0 - All 18 ViewModel classes inherit ObservableObject - Simple properties use [ObservableProperty] field-based source generator - Complex properties (side-effect setters) use SetProperty/OnPropertyChanged - Custom RelayCommand.cs removed, toolkit RelayCommand<object> used - DelegateCommand.cs preserved (used by Calculator UI project) - 3 VMs with OnPropertyChanged hooks use HandlePropertySideEffects + override - All MVVMTK0034/CS0169/CS0219/CS0414 warnings fixed ## UnitConverter Wired to Native CalcManager Engine - UnitConverterDataLoader extends ConverterDataLoaderBase with all 12 categories, 168 unit IDs, and conversion ratios matching C++ main - CurrencyDataLoader fully ported: JSON parsing, cache/web loading, pairwise ratio computation, currency symbols, timestamps - IDL methods marked overridable for C# subclassing - ConverterDataLoaderBridge updated to use IOverrides interface pattern - Full OnPropertyChanged side-effect chain: CurrentCategory, Unit1/2, Value1/2, Value1Active/2Active, SupplementaryResults, CurrencySymbols - PopulateData, ResetCategory, SetSelectedUnits, BuildUnitList - SaveUserPreferences/RestoreUserPreferences via LocalSettings - Proper OnPaste with negate tracking and DisplayPasteError - OnCopyCommand copies unlocalized value (matches C++ behavior) - AnnounceConversionResult uses correct unit order based on active field - RefreshSupplementaryResults includes first whimsical unit - ResetView calls model Reset + OnCategoryChanged - Callbacks marshaled to UI thread via CoreDispatcher - ButtonPressed alias for CalculatorButton {Binding} compatibility Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent a82a3d8 commit 819010c

File tree

6 files changed

+1943
-266
lines changed

6 files changed

+1943
-266
lines changed

src/CalcManager.Interop/UnitConverterImpl.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ namespace winrt::CalcManager::Interop::implementation
1616

1717
void ConverterDataLoaderBridge::LoadData()
1818
{
19-
m_receiver.LoadData();
19+
m_receiver.as<CalcManager::Interop::IConverterDataLoaderBaseOverrides>().LoadData();
2020
}
2121

2222
std::vector<UnitConversionManager::Category> ConverterDataLoaderBridge::GetOrderedCategories()
2323
{
24-
auto categories = m_receiver.GetOrderedCategories();
24+
auto categories = m_receiver.as<CalcManager::Interop::IConverterDataLoaderBaseOverrides>().GetOrderedCategories();
2525
std::vector<UnitConversionManager::Category> result;
2626
result.reserve(categories.size());
2727
for (auto const& cat : categories)
@@ -33,7 +33,7 @@ namespace winrt::CalcManager::Interop::implementation
3333

3434
std::vector<UnitConversionManager::Unit> ConverterDataLoaderBridge::GetOrderedUnits(const UnitConversionManager::Category& c)
3535
{
36-
auto units = m_receiver.GetOrderedUnits(ToWinRTCategory(c));
36+
auto units = m_receiver.as<CalcManager::Interop::IConverterDataLoaderBaseOverrides>().GetOrderedUnits(ToWinRTCategory(c));
3737
std::vector<UnitConversionManager::Unit> result;
3838
result.reserve(units.size());
3939
for (auto const& u : units)
@@ -46,7 +46,7 @@ namespace winrt::CalcManager::Interop::implementation
4646
std::unordered_map<UnitConversionManager::Unit, UnitConversionManager::ConversionData, UnitConversionManager::UnitHash>
4747
ConverterDataLoaderBridge::LoadOrderedRatios(const UnitConversionManager::Unit& u)
4848
{
49-
auto entries = m_receiver.LoadOrderedRatios(ToWinRTUnit(u));
49+
auto entries = m_receiver.as<CalcManager::Interop::IConverterDataLoaderBaseOverrides>().LoadOrderedRatios(ToWinRTUnit(u));
5050
std::unordered_map<UnitConversionManager::Unit, UnitConversionManager::ConversionData, UnitConversionManager::UnitHash> result;
5151
for (auto const& entry : entries)
5252
{
@@ -59,7 +59,7 @@ namespace winrt::CalcManager::Interop::implementation
5959

6060
bool ConverterDataLoaderBridge::SupportsCategory(const UnitConversionManager::Category& target)
6161
{
62-
return m_receiver.SupportsCategory(ToWinRTCategory(target));
62+
return m_receiver.as<CalcManager::Interop::IConverterDataLoaderBaseOverrides>().SupportsCategory(ToWinRTCategory(target));
6363
}
6464

6565
// ---- UnitConverterVMCallbackBridge ----
@@ -72,7 +72,7 @@ namespace winrt::CalcManager::Interop::implementation
7272

7373
void UnitConverterVMCallbackBridge::DisplayCallback(const std::wstring& from, const std::wstring& to)
7474
{
75-
m_receiver.DisplayCallback(hstring(from), hstring(to));
75+
m_receiver.as<CalcManager::Interop::IUnitConverterVMCallbackBaseOverrides>().DisplayCallback(hstring(from), hstring(to));
7676
}
7777

7878
void UnitConverterVMCallbackBridge::SuggestedValueCallback(
@@ -87,12 +87,12 @@ namespace winrt::CalcManager::Interop::implementation
8787
sv.Unit = ToWinRTUnit(unit);
8888
winrtValues.push_back(std::move(sv));
8989
}
90-
m_receiver.SuggestedValueCallback(com_array<CalcManager::Interop::SuggestedValueWrapper>(std::move(winrtValues)));
90+
m_receiver.as<CalcManager::Interop::IUnitConverterVMCallbackBaseOverrides>().SuggestedValueCallback(com_array<CalcManager::Interop::SuggestedValueWrapper>(std::move(winrtValues)));
9191
}
9292

9393
void UnitConverterVMCallbackBridge::MaxDigitsReached()
9494
{
95-
m_receiver.MaxDigitsReached();
95+
m_receiver.as<CalcManager::Interop::IUnitConverterVMCallbackBaseOverrides>().MaxDigitsReached();
9696
}
9797

9898
// ---- ViewModelCurrencyCallbackBridge ----
@@ -105,27 +105,27 @@ namespace winrt::CalcManager::Interop::implementation
105105

106106
void ViewModelCurrencyCallbackBridge::CurrencyDataLoadFinished(bool didLoad)
107107
{
108-
m_receiver.CurrencyDataLoadFinished(didLoad);
108+
m_receiver.as<CalcManager::Interop::IViewModelCurrencyCallbackBaseOverrides>().CurrencyDataLoadFinished(didLoad);
109109
}
110110

111111
void ViewModelCurrencyCallbackBridge::CurrencySymbolsCallback(const std::wstring& fromSymbol, const std::wstring& toSymbol)
112112
{
113-
m_receiver.CurrencySymbolsCallback(hstring(fromSymbol), hstring(toSymbol));
113+
m_receiver.as<CalcManager::Interop::IViewModelCurrencyCallbackBaseOverrides>().CurrencySymbolsCallback(hstring(fromSymbol), hstring(toSymbol));
114114
}
115115

116116
void ViewModelCurrencyCallbackBridge::CurrencyRatiosCallback(const std::wstring& ratioEquality, const std::wstring& accRatioEquality)
117117
{
118-
m_receiver.CurrencyRatiosCallback(hstring(ratioEquality), hstring(accRatioEquality));
118+
m_receiver.as<CalcManager::Interop::IViewModelCurrencyCallbackBaseOverrides>().CurrencyRatiosCallback(hstring(ratioEquality), hstring(accRatioEquality));
119119
}
120120

121121
void ViewModelCurrencyCallbackBridge::CurrencyTimestampCallback(const std::wstring& timestamp, bool isWeekOldData)
122122
{
123-
m_receiver.CurrencyTimestampCallback(hstring(timestamp), isWeekOldData);
123+
m_receiver.as<CalcManager::Interop::IViewModelCurrencyCallbackBaseOverrides>().CurrencyTimestampCallback(hstring(timestamp), isWeekOldData);
124124
}
125125

126126
void ViewModelCurrencyCallbackBridge::NetworkBehaviorChanged(int newBehavior)
127127
{
128-
m_receiver.NetworkBehaviorChanged(newBehavior);
128+
m_receiver.as<CalcManager::Interop::IViewModelCurrencyCallbackBaseOverrides>().NetworkBehaviorChanged(newBehavior);
129129
}
130130

131131
// ---- UnitConverterWrapper ----

src/CalcManager.Interop/UnitConverterInterop.idl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,29 +73,29 @@ namespace CalcManager.Interop
7373
unsealed runtimeclass UnitConverterVMCallbackBase
7474
{
7575
UnitConverterVMCallbackBase();
76-
void DisplayCallback(String fromValue, String toValue);
77-
void SuggestedValueCallback(SuggestedValueWrapper[] suggestedValues);
78-
void MaxDigitsReached();
76+
overridable void DisplayCallback(String fromValue, String toValue);
77+
overridable void SuggestedValueCallback(SuggestedValueWrapper[] suggestedValues);
78+
overridable void MaxDigitsReached();
7979
};
8080

8181
unsealed runtimeclass ViewModelCurrencyCallbackBase
8282
{
8383
ViewModelCurrencyCallbackBase();
84-
void CurrencyDataLoadFinished(Boolean didLoad);
85-
void CurrencySymbolsCallback(String fromSymbol, String toSymbol);
86-
void CurrencyRatiosCallback(String ratioEquality, String accRatioEquality);
87-
void CurrencyTimestampCallback(String timestamp, Boolean isWeekOldData);
88-
void NetworkBehaviorChanged(Int32 newBehavior);
84+
overridable void CurrencyDataLoadFinished(Boolean didLoad);
85+
overridable void CurrencySymbolsCallback(String fromSymbol, String toSymbol);
86+
overridable void CurrencyRatiosCallback(String ratioEquality, String accRatioEquality);
87+
overridable void CurrencyTimestampCallback(String timestamp, Boolean isWeekOldData);
88+
overridable void NetworkBehaviorChanged(Int32 newBehavior);
8989
};
9090

9191
unsealed runtimeclass ConverterDataLoaderBase
9292
{
9393
ConverterDataLoaderBase();
94-
void LoadData();
95-
CategoryWrapper[] GetOrderedCategories();
96-
UnitWrapper[] GetOrderedUnits(CategoryWrapper category);
97-
UnitConversionEntry[] LoadOrderedRatios(UnitWrapper unit);
98-
Boolean SupportsCategory(CategoryWrapper target);
94+
overridable void LoadData();
95+
overridable CategoryWrapper[] GetOrderedCategories();
96+
overridable UnitWrapper[] GetOrderedUnits(CategoryWrapper category);
97+
overridable UnitConversionEntry[] LoadOrderedRatios(UnitWrapper unit);
98+
overridable Boolean SupportsCategory(CategoryWrapper target);
9999
};
100100

101101
runtimeclass UnitConverterWrapper

0 commit comments

Comments
 (0)