mirror of
https://github.com/Microsoft/calculator.git
synced 2025-08-22 14:13:30 -07:00
fixes EETypeLoadException issue: export class DelegateCommand (#18)
* fixes EETypeLoadException issue: export class DelegateCommand * weak-reference in C++/CX * WeakRef in C# codebase * UTF-8-BOM * spaces in macro * resolve some comments from the offline review * format * rename file
This commit is contained in:
parent
5a8423947f
commit
b53600bfc4
9 changed files with 78 additions and 73 deletions
|
@ -7,18 +7,14 @@ namespace CalculatorApp
|
|||
{
|
||||
namespace Common
|
||||
{
|
||||
template <typename TTarget>
|
||||
ref class DelegateCommand : public Windows::UI::Xaml::Input::ICommand
|
||||
public delegate void DelegateCommandHandler(Platform::Object ^ parameter);
|
||||
|
||||
public ref class DelegateCommand sealed : public Windows::UI::Xaml::Input::ICommand
|
||||
{
|
||||
internal :
|
||||
|
||||
typedef void (TTarget::*CommandHandlerFunc)(Platform::Object ^);
|
||||
|
||||
DelegateCommand(TTarget ^ target, CommandHandlerFunc func)
|
||||
: m_weakTarget(target)
|
||||
, m_function(func)
|
||||
{
|
||||
}
|
||||
public:
|
||||
DelegateCommand(DelegateCommandHandler ^ handler)
|
||||
: m_handler(handler)
|
||||
{}
|
||||
|
||||
private:
|
||||
// Explicit, and private, implementation of ICommand, this way of programming makes it so
|
||||
|
@ -27,11 +23,7 @@ namespace CalculatorApp
|
|||
// code in the app calling Execute.
|
||||
virtual void ExecuteImpl(Platform::Object ^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::Execute
|
||||
{
|
||||
TTarget ^ target = m_weakTarget.Resolve<TTarget>();
|
||||
if (target)
|
||||
{
|
||||
(target->*m_function)(parameter);
|
||||
}
|
||||
m_handler->Invoke(parameter);
|
||||
}
|
||||
|
||||
virtual bool CanExecuteImpl(Platform::Object ^ parameter) sealed = Windows::UI::Xaml::Input::ICommand::CanExecute
|
||||
|
@ -39,9 +31,9 @@ namespace CalculatorApp
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual event Windows::Foundation::EventHandler<Platform::Object^>^ CanExecuteChangedImpl
|
||||
virtual event Windows::Foundation::EventHandler<Platform::Object ^> ^ CanExecuteChangedImpl
|
||||
{
|
||||
virtual Windows::Foundation::EventRegistrationToken add(Windows::Foundation::EventHandler<Platform::Object^>^ handler) sealed = Windows::UI::Xaml::Input::ICommand::CanExecuteChanged::add
|
||||
virtual Windows::Foundation::EventRegistrationToken add(Windows::Foundation::EventHandler<Platform::Object ^> ^ handler) sealed = Windows::UI::Xaml::Input::ICommand::CanExecuteChanged::add
|
||||
{
|
||||
return m_canExecuteChanged += handler;
|
||||
}
|
||||
|
@ -52,17 +44,25 @@ namespace CalculatorApp
|
|||
}
|
||||
|
||||
private:
|
||||
DelegateCommandHandler ^ m_handler;
|
||||
|
||||
event Windows::Foundation::EventHandler<Platform::Object^>^ m_canExecuteChanged;
|
||||
|
||||
CommandHandlerFunc m_function;
|
||||
Platform::WeakReference m_weakTarget;
|
||||
event Windows::Foundation::EventHandler<Platform::Object ^> ^ m_canExecuteChanged;
|
||||
};
|
||||
|
||||
template <typename TTarget, typename TFuncPtr>
|
||||
DelegateCommand<TTarget> ^ MakeDelegate(TTarget ^ target, TFuncPtr&& function) {
|
||||
return ref new DelegateCommand<TTarget>(target, std::forward<TFuncPtr>(function));
|
||||
}
|
||||
|
||||
DelegateCommandHandler ^ MakeDelegateCommandHandler(TTarget ^ target, TFuncPtr&& function)
|
||||
{
|
||||
Platform::WeakReference weakTarget(target);
|
||||
return ref new DelegateCommandHandler([weakTarget, function=std::forward<TFuncPtr>(function)](Platform::Object ^ param)
|
||||
{
|
||||
TTarget ^ thatTarget = weakTarget.Resolve<TTarget>();
|
||||
if (nullptr != thatTarget)
|
||||
{
|
||||
(thatTarget->*function)(param);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -168,11 +168,22 @@ public:
|
|||
// The variable member generated by this macro should not be used in the class code, use the
|
||||
// property getter instead.
|
||||
#define COMMAND_FOR_METHOD(p, m) \
|
||||
property Windows::UI::Xaml::Input::ICommand^ p {\
|
||||
Windows::UI::Xaml::Input::ICommand^ get() {\
|
||||
if (!donotuse_##p) {\
|
||||
donotuse_##p = CalculatorApp::Common::MakeDelegate(this, &m);\
|
||||
} return donotuse_##p; }} private: Windows::UI::Xaml::Input::ICommand^ donotuse_##p; \
|
||||
property Windows::UI::Xaml::Input::ICommand ^ p \
|
||||
{ \
|
||||
Windows::UI::Xaml::Input::ICommand ^ get() \
|
||||
{ \
|
||||
if (!donotuse_##p) \
|
||||
{ \
|
||||
donotuse_##p = ref new CalculatorApp::Common::DelegateCommand( \
|
||||
CalculatorApp::Common::MakeDelegateCommandHandler(this, &m) \
|
||||
); \
|
||||
} \
|
||||
return donotuse_##p; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
private: \
|
||||
Windows::UI::Xaml::Input::ICommand ^ donotuse_##p; \
|
||||
\
|
||||
public:
|
||||
|
||||
|
|
|
@ -151,11 +151,11 @@
|
|||
<Compile Include="Converters\ItemSizeToVisibilityConverter.cs" />
|
||||
<Compile Include="Converters\RadixToStringConverter.cs" />
|
||||
<Compile Include="Converters\VisibilityNegationConverter.cs" />
|
||||
<Compile Include="DelegateCommand.cs" />
|
||||
<Compile Include="EquationStylePanelControl.xaml.cs">
|
||||
<DependentUpon>EquationStylePanelControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="KeyGraphFeaturesTemplateSelector.cs" />
|
||||
<Compile Include="Utils\DelegateCommandUtils.cs" />
|
||||
<Compile Include="Views\Calculator.xaml.cs">
|
||||
<DependentUpon>Calculator.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace CalculatorApp.Common
|
||||
{
|
||||
internal class DelegateCommand<TTarget> : System.Windows.Input.ICommand
|
||||
{
|
||||
public delegate void CommandHandlerFunc(object obj);
|
||||
|
||||
public DelegateCommand(TTarget target, CommandHandlerFunc func)
|
||||
{
|
||||
m_weakTarget = new WeakReference(target);
|
||||
m_function = func;
|
||||
}
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Execute(object parameter)
|
||||
{
|
||||
object target = m_weakTarget.Target;
|
||||
if (target != null && target is TTarget)
|
||||
{
|
||||
m_function(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
private CommandHandlerFunc m_function;
|
||||
private WeakReference m_weakTarget;
|
||||
}
|
||||
}
|
||||
|
26
src/Calculator/Utils/DelegateCommandUtils.cs
Normal file
26
src/Calculator/Utils/DelegateCommandUtils.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using CalculatorApp.Common;
|
||||
|
||||
namespace CalculatorApp.Utils
|
||||
{
|
||||
static class DelegateCommandUtils
|
||||
{
|
||||
public static DelegateCommand MakeDelegateCommand<TTarget>(TTarget target, DelegateCommandHandler handler)
|
||||
where TTarget : class
|
||||
{
|
||||
WeakReference weakTarget = new WeakReference(target);
|
||||
return new DelegateCommand(param =>
|
||||
{
|
||||
TTarget thatTarget = weakTarget.Target as TTarget;
|
||||
if(null != thatTarget)
|
||||
{
|
||||
handler.Invoke(param);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ using CalculatorApp;
|
|||
using CalculatorApp.Common;
|
||||
using CalculatorApp.Converters;
|
||||
using CalculatorApp.Controls;
|
||||
using CalculatorApp.Utils;
|
||||
using CalculatorApp.ViewModel;
|
||||
|
||||
using Windows.Foundation;
|
||||
|
@ -140,7 +141,7 @@ namespace CalculatorApp
|
|||
{
|
||||
if (donotuse_HistoryButtonPressed == null)
|
||||
{
|
||||
donotuse_HistoryButtonPressed = new DelegateCommand<Calculator>(this, ToggleHistoryFlyout);
|
||||
donotuse_HistoryButtonPressed = DelegateCommandUtils.MakeDelegateCommand(this, ToggleHistoryFlyout);
|
||||
}
|
||||
return donotuse_HistoryButtonPressed;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ using System.Collections.Generic;
|
|||
using System.Threading.Tasks;
|
||||
using System.Diagnostics;
|
||||
using CalculatorApp;
|
||||
using CalculatorApp.Utils;
|
||||
using CalculatorApp.ViewModel;
|
||||
|
||||
using Windows.Foundation;
|
||||
|
@ -47,7 +48,7 @@ namespace CalculatorApp
|
|||
{
|
||||
if (donotuse_ButtonPressed == null)
|
||||
{
|
||||
donotuse_ButtonPressed = new CalculatorApp.Common.DelegateCommand<CalculatorScientificAngleButtons>(this, OnAngleButtonPressed);
|
||||
donotuse_ButtonPressed = DelegateCommandUtils.MakeDelegateCommand(this, OnAngleButtonPressed);
|
||||
}
|
||||
return donotuse_ButtonPressed;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ using CalculatorApp;
|
|||
using CalculatorApp.Common;
|
||||
using CalculatorApp.Common.Automation;
|
||||
using CalculatorApp.Controls;
|
||||
using CalculatorApp.Utils;
|
||||
using CalculatorApp.ViewModel;
|
||||
//using CalcManager.NumberFormattingUtils;
|
||||
using GraphControl;
|
||||
|
@ -114,7 +115,7 @@ namespace CalculatorApp
|
|||
{
|
||||
if (donotuse_ZoomOutButtonPressed == null)
|
||||
{
|
||||
donotuse_ZoomOutButtonPressed = new DelegateCommand<GraphingCalculator>(this, OnZoomOutCommand);
|
||||
donotuse_ZoomOutButtonPressed = DelegateCommandUtils.MakeDelegateCommand(this, OnZoomOutCommand);
|
||||
}
|
||||
return donotuse_ZoomOutButtonPressed;
|
||||
}
|
||||
|
@ -127,7 +128,7 @@ namespace CalculatorApp
|
|||
{
|
||||
if (donotuse_ZoomInButtonPressed == null)
|
||||
{
|
||||
donotuse_ZoomInButtonPressed = new DelegateCommand<GraphingCalculator>(this, OnZoomInCommand);
|
||||
donotuse_ZoomInButtonPressed = DelegateCommandUtils.MakeDelegateCommand(this, OnZoomInCommand);
|
||||
}
|
||||
return donotuse_ZoomInButtonPressed;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Windows.Input;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using CalculatorApp.Utils;
|
||||
|
||||
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
|
@ -16,8 +17,7 @@ namespace CalculatorApp
|
|||
{
|
||||
if (donotuse_BitLengthButtonPressed == null)
|
||||
{
|
||||
donotuse_BitLengthButtonPressed =
|
||||
new Common.DelegateCommand<CalculatorProgrammerDisplayPanel>(this, OnBitLengthButtonPressed);
|
||||
donotuse_BitLengthButtonPressed = DelegateCommandUtils.MakeDelegateCommand(this, OnBitLengthButtonPressed);
|
||||
}
|
||||
return donotuse_BitLengthButtonPressed;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue