Overview
DaisyModal is a modal dialog overlay with backdrop, supporting draggable positioning, ESC key to close, and click-outside-to-close behavior.
Properties
IsOpen
Controls whether the modal is visible. Setting to true opens the modal, false closes it.
IsDraggable
Whether the dialog can be dragged by pointer. When enabled, a grab bar appears at the top.
Corner Radius
Corner radius for the top-left corner.
Corner radius for the top-right corner.
Corner radius for the bottom-left corner.
Corner radius for the bottom-right corner.
Protected Properties
These properties can be overridden in derived classes:
Margin between the dialog and the viewport edges. Controls max width/height and drag bounds.
Panel for adding overlay elements on top of the dialog content.
Current X/Y offset of the dialog from its centered position.
Protected Methods
SetDialogSize()
Sets the dialog host size. Useful for derived classes that calculate their own sizing.
protected void SetDialogSize(double width, double height)
ShouldCloseOnOutsideClick()
Controls whether tapping outside the dialog closes the modal. Override to customize.
protected virtual bool ShouldCloseOnOutsideClick() // Returns true by default
GetNeumorphicHostElement()
Returns the element that receives neumorphic effects (the dialog host).
protected override FrameworkElement? GetNeumorphicHostElement()
Usage Examples
XAML - Basic Modal
<controls:DaisyModal x:Name="MyModal">
<StackPanel Padding="24" Spacing="16">
<TextBlock Text="Modal Title" FontSize="20" FontWeight="SemiBold" />
<TextBlock Text="This is a modal dialog." TextWrapping="Wrap" />
<controls:DaisyButton
Content="Close"
Click="CloseModal" />
</StackPanel>
</controls:DaisyModal>
private void OpenModal(object sender, RoutedEventArgs e)
{
MyModal.IsOpen = true;
}
private void CloseModal(object sender, RoutedEventArgs e)
{
MyModal.IsOpen = false;
}
XAML - Draggable Modal
<controls:DaisyModal IsDraggable="True">
<StackPanel Padding="24" Spacing="12">
<TextBlock Text="Drag me!" FontSize="18" FontWeight="SemiBold" />
<TextBlock Text="You can drag this modal by the grab bar at the top." TextWrapping="Wrap" />
</StackPanel>
</controls:DaisyModal>
XAML - Custom Corner Radius
<!-- Rounded top corners only -->
<controls:DaisyModal
TopLeftRadius="24"
TopRightRadius="24"
BottomLeftRadius="0"
BottomRightRadius="0">
<TextBlock Text="Custom corners" Padding="24" />
</controls:DaisyModal>
XAML - Modal with Actions
<controls:DaisyModal x:Name="ConfirmModal">
<StackPanel Padding="24" Spacing="16">
<TextBlock Text="Confirm Action" FontSize="20" FontWeight="SemiBold" />
<TextBlock Text="Are you sure you want to proceed?" TextWrapping="Wrap" />
<StackPanel Orientation="Horizontal" Spacing="8" HorizontalAlignment="Right">
<controls:DaisyButton
Content="Cancel"
Variant="Ghost"
Click="CancelAction" />
<controls:DaisyButton
Content="Confirm"
Variant="Primary"
Click="ConfirmAction" />
</StackPanel>
</StackPanel>
</controls:DaisyModal>
C# - Programmatic Modal
var modal = new DaisyModal
{
Content = new StackPanel
{
Padding = new Thickness(24),
Spacing = 16,
Children =
{
new TextBlock
{
Text = "Dynamic Modal",
FontSize = 20,
FontWeight = FontWeights.SemiBold
},
new TextBlock
{
Text = "This modal was created programmatically.",
TextWrapping = TextWrapping.Wrap
}
}
}
};
// Add to page
RootGrid.Children.Add(modal);
// Open modal
modal.IsOpen = true;
C# - Custom Derived Modal
public class CustomModal : DaisyModal
{
protected override bool ShouldCloseOnOutsideClick()
{
// Prevent closing when clicking outside
return false;
}
protected override double DialogBoundsMargin => 32; // Larger margin
public CustomModal()
{
// Set custom size
SetDialogSize(400, 300);
// Custom corner radius
TopLeftRadius = 24;
TopRightRadius = 24;
BottomLeftRadius = 8;
BottomRightRadius = 8;
}
}
C# - Modal with Callback
public void ShowConfirmDialog(Action onConfirm, Action onCancel)
{
var modal = new DaisyModal();
var stack = new StackPanel
{
Padding = new Thickness(24),
Spacing = 16
};
stack.Children.Add(new TextBlock
{
Text = "Confirm?",
FontSize = 18,
FontWeight = FontWeights.SemiBold
});
var buttonPanel = new StackPanel
{
Orientation = Orientation.Horizontal,
Spacing = 8,
HorizontalAlignment = HorizontalAlignment.Right
};
var cancelBtn = new DaisyButton
{
Content = "Cancel",
Variant = DaisyButtonVariant.Ghost
};
cancelBtn.Click += (s, e) =>
{
modal.IsOpen = false;
onCancel?.Invoke();
};
var confirmBtn = new DaisyButton
{
Content = "Confirm",
Variant = DaisyButtonVariant.Primary
};
confirmBtn.Click += (s, e) =>
{
modal.IsOpen = false;
onConfirm?.Invoke();
};
buttonPanel.Children.Add(cancelBtn);
buttonPanel.Children.Add(confirmBtn);
stack.Children.Add(buttonPanel);
modal.Content = stack;
RootGrid.Children.Add(modal);
modal.IsOpen = true;
}
Behavior Notes
- ESC Key: Pressing ESC closes the modal (when
IsOpen="True")
- Click Outside: Clicking the backdrop closes the modal by default (override
ShouldCloseOnOutsideClick() to change)
- Focus: Modal automatically receives focus when opened to capture keyboard events
- Drag Bounds: When
IsDraggable="True", the dialog is constrained within the viewport with DialogBoundsMargin spacing
- Hit Testing: When closed, the modal is not hit-testable, allowing interaction with elements behind it
- Z-Index: Modal uses ThemeShadow with elevation (Z=32) for depth
Theming
The modal respects these theme resources:
DaisyModalBackdropBrush - Backdrop overlay color (default: semi-transparent black)
DaisyModalBackground - Dialog background color (default: Base100)
DaisyModalForeground - Dialog text color (default: BaseContent)
DaisyModalGrabBarBrush - Grab bar color (default: Base300)