Seria pytań uczestników, które pojawiły się podczas szkolenia WPF dla zaawansowanych realizowanego w dniach 26-30.04.2021 r.
Tak, można to uzyskać za pomocą nieudokumentowanej funkcji:
UserControl
<d:DesignerProperties.DesignStyle>
<Style TargetType="UserControl">
<Setter Property="Background" Value="DarkGray" />
</Style>
</d:DesignerProperties.DesignStyle>
Page
<d:DesignerProperties.DesignStyle>
<Style TargetType="Page">
<Setter Property="Background" Value="DarkBlue" />
</Style>
</d:DesignerProperties.DesignStyle>
Styl taki można przenieść do zasobów i skorzystać z niego na UserControl:
<Style x:Key="MyDesignUserControlStyle" TargetType="UserControl">
<Setter Property="Background" Value="DarkGreen" />
<Setter Property="Foreground" Value="White" />
</Style>
<UserControl
d:DesignHeight="450"
d:DesignStyle="{StaticResource MyDesignUserControlStyle}"
d:DesignWidth="800"
mc:Ignorable="d">
Niestety właściwość Source nie jest typu DependencyProperty i przez to nie można jej powiązać za pomocą Bindingu. Ale jak sposób na obejście tego problemu...
Należy utworzyć Attached Property:
public static class WebView2AttachedProperty
{
public static readonly DependencyProperty BindableSourceProperty =
DependencyProperty.RegisterAttached("BindableSource",
typeof(string), typeof(WebView2AttachedProperty), new PropertyMetadata(null, BindableSourcePropertyChanged));
private static void BindableSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var webBrowser = (WebView2)d;
webBrowser.Source = new Uri((string)e.NewValue);
}
public static string GetBindableSource(DependencyObject obj)
{
return (string)obj.GetValue(BindableSourceProperty);
}
public static void SetBindableSource(DependencyObject obj, string value)
{
obj.SetValue(BindableSourceProperty, value);
}
}
1. Tworzymy przekierowanie zdarzenia Drop na komendę:
<wv2:WebView2 ap:WebView2AttachedProperty.BindableSource="{Binding Url}" />
1. Tworzymy przekierowanie zdarzenia Drop na komendę:
<ListBox AllowDrop="True">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Drop">
<i:InvokeCommandAction
Command="{Binding DropRemoveCustomerCommand}"
EventArgsConverter="{c:DragEventArgsConverter}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
Podpinamy konwerter, który pobierze przeciągany obiekt modelu:
public class DragEventArgsConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DragEventArgs e = (DragEventArgs)value;
Customer customer = e.Data.GetData(typeof(Customer)) as Customer;
return customer;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
Tworzymy własne MarkupExtension do obsługi zdarzenia Move:
public class MouseMoveMarkupExtension : MarkupExtension
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new MouseEventHandler(OnMouseEventHandler);
}
private void OnMouseEventHandler(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Selector selector = sender as Selector;
DragDrop.DoDragDrop(selector, selector.SelectedItem, DragDropEffects.Move);
}
}
}
Podpinamy powyższą klasę pod zdarzenie MouseMove:
<ListBox MouseMove="{me:MouseMoveMarkup}" >
</ListBox>