我有一个自定义控件,如:
public sealed class BorderEx : Control
{
public static readonly RoutedEvent ReloadClickEvent = EventManager.RegisterRoutedEvent("ReloadClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(BorderEx));
public event RoutedEventHandler ReloadClick
{
add { AddHandler(ReloadClickEvent, value); }
remove { RemoveHandler(ReloadClickEvent, value); }
}
void RaiseReloadClickEvent()
{
var newEventArgs = new RoutedEventArgs(ReloadClickEvent);
RaiseEvent(newEventArgs);
}
static BorderEx()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BorderEx), new FrameworkPropertyMetadata(typeof(BorderEx)));
}
}
并且reloadButton点击了generic.xaml
时出现了事件<ControlTemplate TargetType="{x:Type cbr:BorderEx}">
<ControlTemplate.Triggers>
<Trigger SourceName="reloadButton" Property="IsPressed" Value="True">
<Setter TargetName="reloadButton" Property="Background" Value="Green"/>
<EventSetter Event="ReloadClick" Handler="RaiseReloadClickEvent"></EventSetter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate
但我不知道如何从内部按钮引发此外部事件。花了最后几个小时谷歌搜索,最终没有任何结果。以上EventSetter不起作用。
答案 0 :(得分:3)
这部分还可以,
public static readonly RoutedEvent ReloadClickEvent = EventManager.RegisterRoutedEvent("ReloadClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(BorderEx));
public event RoutedEventHandler ReloadClick
{
add { AddHandler(ReloadClickEvent, value); }
remove { RemoveHandler(ReloadClickEvent, value); }
}
static BorderEx()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BorderEx), new FrameworkPropertyMetadata(typeof(BorderEx)));
}
我必须创建依赖属性,所以我可以在click事件
上更改一些值 public static readonly DependencyProperty ReloadProperty = DependencyProperty.Register("Reload", typeof (bool), typeof (BorderEx), new PropertyMetadata(default(bool), ReloadClicked));
public bool Reload
{
get { return (bool) GetValue(ReloadProperty); }
set { SetValue(ReloadProperty, value); }
}
我可以在更改时触发的其他方法中处理它
private static void ReloadClicked(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
if (!((bool) e.NewValue)) return;
var sender = (BorderEx) o;
sender.RaiseEvent(new RoutedEventArgs(ReloadClickEvent));
}
然后只需更改点击值
<ControlTemplate.Triggers>
<Trigger SourceName="reloadButton" Property="IsPressed" Value="True">
<Setter TargetName="reloadButton" Property="Background" Value="Green"/>
<Setter Property="Reload" Value="True"/>
</Trigger>
</ControlTemplate.Triggers>
答案 1 :(得分:2)
您的活动看起来很棒,但无法在触发器中设置EventSetter
这一事实。引自link:
因为使用EventSetter连接事件处理程序是一个编译时功能,它通过IStyleConnector接口检测,所以有另一个名为IComponentConnector的接口,XAML编译器使用该接口为独立的XAML元素连接事件处理程序。
你可以这样做。识别EventSetter
外部触发器,例如早期Style
/ Template
:
<Style TargetType="{x:Type local:BorderEx}">
<EventSetter Event="Button.Click" Handler="ReloadClickEvent" />
...
</Style>
Code behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ReloadClickEvent(object sender, RoutedEventArgs e)
{
RaiseEvent(new DemoEventArgs(BorderEx.ReloadClickEvent, sender));
}
}
public class DemoEventArgs : RoutedEventArgs
{
public DemoEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source)
{
MessageBox.Show("Raise!");
}
}
public sealed class BorderEx : Control
{
public static readonly RoutedEvent ReloadClickEvent = EventManager.RegisterRoutedEvent("ReloadClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(BorderEx));
public event RoutedEventHandler ReloadClick
{
add { AddHandler(ReloadClickEvent, value); }
remove { RemoveHandler(ReloadClickEvent, value); }
}
private void RaiseReloadClickEvent()
{
var newEventArgs = new RoutedEventArgs(ReloadClickEvent);
RaiseEvent(newEventArgs);
}
static BorderEx()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BorderEx), new FrameworkPropertyMetadata(typeof(BorderEx)));
}
}
或者,也可以使用DependencyProperty
(也可以附加)。例如:
属性定义:
public static readonly DependencyProperty SampleProperty =
DependencyProperty.RegisterAttached("Sample",
typeof(bool),
typeof(SampleClass),
new UIPropertyMetadata(false, OnSample));
private static void OnSample(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is bool && ((bool)e.NewValue) == true)
{
// do something...
}
}
在XAML中调用。
在EventTrigger
:
<EventTrigger SourceName="MyButton" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyBox" Storyboard.TargetProperty="(local:SampleClass.Sample)">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<sys:Boolean>True</sys:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
与DataTrigger
一起使用(Style
/ DataTemplate
/ etc
):
<DataTrigger Binding="{Binding ElementName=MyBox, Path=Status), Mode=OneWay}" Value="True">
<Setter Property="(local:SampleClass.Sample)" Value="True" />
</DataTrigger>
与Trigger
一起使用(在Style
中):
<Trigger Property="MyCheckBox.IsChecked" Value="True">
<Setter Property="(local:SampleClass.Sample)" Value="True" />
</Trigger>
使用后面的代码:
private void Clear_Click(object sender, RoutedEventArgs e)
{
SampleClass.SetSampleClass(MyBox, true);
}