我正在制作Windows 10 UWP应用。 为简单起见,我们说我的页面上有一个 TextBox 。在这个 TextBox 下有我的3种(不同类型)自定义控件。如果用户单击其中一个控件内的按钮,则这3个控件具有相同的属性和事件,订阅此事件的方法会导致 TextBox 中的文本被分配给控件中的 SomeProperty 。
是否有某种方式可以订阅这些活动,因此我不必使用3种不同的方法处理它,而它们确实在做同样的事情,但是对于3种不同的控件。
这是所有控件共有的代码。有MyControlA,MyControlB和MyControlC
public sealed partial class MyControlA : UserControl
{
public delegate void StartPositionClickedEventHandler(object sender, EventArgs e);
public event StartPositionClickedEventHandler StartPositionClicked;
public string SomeProperty
{
get { return (string)GetValue(SomePropertyProperty); }
set { SetValue(SomePropertyProperty, value); }
}
private void StartPosition_Click(object sender, RoutedEventArgs e)
{
StartPositionClicked?.Invoke(this, EventArgs.Empty);
}
// Using a DependencyProperty as the backing store for SomeProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SomePropertyProperty =
DependencyProperty.Register("SomeProperty", typeof(string), typeof(MyControlA), null);
}
我在控件
的页面中订阅了该事件_control.StartPositionClicked += new MyControlA.StartPositionClickedEventHandler(SetCurrentStartPositon);
并处理它
private void SetCurrentStartPositon(object sender, EventArgs e)
{
_control.SomeProperty = DummyTextBox.Text;
}
我必须为所有控件执行此操作,但我可能会有很多这些控件,因为它们是在需要时以编程方式创建的,所以我希望有更好的方法来执行它。我想到的一切似乎都是愚蠢的或超级低效的。
提前谢谢!
答案 0 :(得分:1)
是的,你可以!
它被称为EventSetter
,您可以像这样使用它:
<Style TargetType="{x:Type local:MyControlA}">
<EventSetter Event="StartPositionClicked" Handler="SomeAction"/>
</Style>
您需要将此样式放在父控件中,即Grid
或StackPanel
,您还需要实现SomeAction
方法。
HTH
答案 1 :(得分:1)
由于您的所有控件都具有相同类型的相同属性,因此有两种方法可以实现您的目标:
1:创建一个基类,它将实现它们共有的代码,并使所有控件继承自它:
public abstract class MyControlBase : UserControl
{
public delegate void StartPositionClickedEventHandler(object sender, EventArgs e);
public event StartPositionClickedEventHandler StartPositionClicked;
public string SomeProperty
{
get { return (string)GetValue(SomePropertyProperty); }
set { SetValue(SomePropertyProperty, value); }
}
protected void StartPosition_Click(object sender, RoutedEventArgs e)
{
StartPositionClicked?.Invoke(this, EventArgs.Empty);
}
// Using a DependencyProperty as the backing store for SomeProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SomePropertyProperty =
DependencyProperty.Register("SomeProperty", typeof(string), typeof(MyControlA), null);
}
public sealed partial class MyControlA : MyControlBase
{
// Class specific code
}
请注意,您还需要更改XAML中的基类,而不是像
那样<UserControl>
<!-- Your XAML code -->
</UserControl>
你必须使用这样的东西,假设xmlns:local
指向MyControlBase
所在的命名空间:
<local:MyControlBase>
<!-- Your XAML code -->
</local:MyControlBase>
然后你可以创建一个类似于这个的事件处理程序:
private void SetCurrentStartPositon(object sender, EventArgs e)
{
// Get the control that invoked this event
MyControlBase senderControl = (MyControlBase)sender;
senderControl.SomeProperty = DummyTextBox.Text;
}
2:为它们创建一个简单的界面,并使所有三个控件都从中继承:
public interface IMyControl
{
string SomeProperty { get; set; }
}
因此,在您的代码中,您可以将所有控件的事件订阅到一个看起来像这样的方法:
private void SetCurrentStartPositon(object sender, EventArgs e)
{
// Get the control that invoked this event
IMyControl senderControl = (IMyControl)sender;
senderControl.SomeProperty = DummyTextBox.Text;
}
我建议使用第一个选项,因为它使您的代码更易于阅读,并避免了更改公共代码时可能出现的不一致。