Reputation: 1961
I've created a CustomControl
in WinUI 3 with some custom properties (DependencyProperty
).
Now I also want to add a custom Event
(not sure if it has to be a RoutedEvent
?) that has to trigger whenever the CurrentStatus
property of my control changes. I'd like to be able to manage it just like a simple Button's Click
, so something like:
public sealed class MyCustomTextBlock : Control
{
public enum Status
{
Waiting,
Busy,
}
private Status currentStatus;
public Status CurrentStatus
{
get { return currentStatus; }
}
public MyCustomTextBlock()
{
this.DefaultStyleKey = typeof(MyCustomTextBlock);
currentStatus = Status.Waiting;
}
// The currentStatus variable is set on some custom methods inside the implementation of the control.
}
<local:MyCustomTextBlock x:Name="MessageBlock"
Message="{TemplateBinding Message}"
DisplayMode="{TemplateBinding DisplayMode}"
StatusChanged="MessageBlock_StatusChanged">
</local:MyCustomTextBlock>
private void MessageBlock_StatusChanged(object sender, RoutedEventArgs e)
{
// Check the CurrentStatus property
if (MyCustomTextBlock.CurrentStatus == MyCustomTextBlock.Status.Waiting)
// Do something...
}
How should I declare the Event and the EventHandler on the code behind of the MyCustomTextBlock
control?
I'm new to WinUI 3 and XAML and looking for "winui 3 custom event" I found this but it's related to WPF and so I cannot find the EventManager.RegisterRoutedEvent()
which is cited in the WinUI Microsoft.UI.Xaml
library.
I followed @AndrewKeepCoding suggestion and now this is my code on the MainWindow
page where I placed MyCustomTextBlock
control.
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
<local:MyCustomTextBlock x:Name="MessageBlock"
Message="{TemplateBinding Message}"
DisplayMode="{TemplateBinding DisplayMode}"
StatusChanged="MessageBlock_StatusChanged">
</local:MyCustomTextBlock>
</StackPanel>
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
private void MessageBlock_StatusChanged(object sender, StatusChangedEventArgs e)
{
MyCustomTextBlock control = (MyCustomTextBlock)sender;
if (e.NewValue == Status.Waiting)
{
// Do something...
}
else if (e.NewValue == Status.Busy)
{
// Do something else...
}
}
}
There's no warnings or compilation errors, but now every time I start the application in debug mode it crashes without trapping any specific Exception with the following error description:
Win32 unmanaged Exception in [10584] WinUI3TestApp.exe
The MainWindow.InitializeComponent()
method is called without any issue but after passing the last line of the the public MyCustomTextBlock()
constructor method, I don't know what happens but something makes the app crash.
It seems to be related to this Microsoft.UI.Xaml
Issue. There's probably something wrong somewhere inside an async method but it's not possible to catch the Exception due to this bug.
Workaround
My problem is related to the Event handler method added in XAML (StatusChanged="MessageBlock_StatusChanged"
).
After removing it and replacing with the event handler declaration (MessageBlock.StatusChanged += MessageBlock_StatusChanged;
) in code behind on MyCustomTextBlock.Loaded()
method, everything worked correctly.
Upvotes: 0
Views: 1688
Reputation: 13666
You can implement a custom EventHandler
like this.
public class StatusChangedEventArgs : EventArgs
{
public Status OldValue { get; }
public Status NewValue { get; }
public StatusChangedEventArgs(Status oldValue, Status newValue)
{
OldValue = oldValue;
NewValue = newValue;
}
}
public sealed class MyCustomTextBlock : Control
{
public enum Status
{
Waiting,
Busy,
}
private Status currentStatus;
public Status CurrentStatus
{
get { return currentStatus; }
}
public MyCustomTextBlock()
{
this.DefaultStyleKey = typeof(MyCustomTextBlock);
currentStatus = Status.Waiting;
}
public event EventHandler<StatusChangedEventArgs>? StatusChanged;
protected void OnStatusChanged(Status oldValue, Status newValue)
{
StatusChanged?.Invoke(this, new StatusChangedEventArgs(oldValue, newValue));
}
}
Upvotes: 1