WPF - 父级如何知道“已检查”子控件复选框的事件?

发布于 2024-11-03 20:56:41 字数 2478 浏览 1 评论 0原文

我有一个带有复选框和网络浏览器的子控件:

<UserControl x:Class="Some.MyUserControl" etc.>
  <Grid>
    <CheckBox x:Name="chkA" Content="Analysis" Checked="chkA_Checked"></CheckBox>
    <WebBrowser Margin="0,30,0,0" Name="wbA"></WebBrowser>
  </Grid>
</UserControl>

我将此控件放入我的 MainWindow.xaml/.cs 中:

<Window x:Class Some.MainWindow xmlns:local="clr-namespace:Some" etc.>
  <Grid>
    <local:MyUserControl x:Name="MyUserControl_Main"></local:MyUserControl>
  </Grid>
</Window>

我的问题是我的 MainWindow 如何知道 CheckBox (chkA) 已被选中?到目前为止,只有实际的用户控件知道它已被单击?如何公开“Checked”事件供我的主窗口查看?或者有更好的方法吗?

我在网上搜索过,但似乎无法理解我所看到的内容。

预先感谢您,

-newb

编辑1:

我正在尝试以下操作,但没有运气,但可能走在正确的轨道上。

在我的 MainWindow.xaml.cs 中,我添加了:

public static readonly RoutedEvent CheckedEvent = EventManager.RegisterRoutedEvent("Checked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyUserControl));

public event RoutedEventHandler Checked
{
    add { AddHandler(CheckedEvent, value); }
    remove { RemoveHandler(CheckedEvent, value); }
}

在 MyUserControl.xaml.cs 中,我添加了:

private void chkA_Checked(object sender, RoutedEventArgs e)
{
    RoutedEventArgs args = new RoutedEventArgs(MainWindow.CheckedEvent);
    RaiseEvent(args);
}

编辑 2:

将前面提到的代码移至 MyUserControl.xaml.cs:

public static readonly RoutedEvent CheckedEvent = EventManager.RegisterRoutedEvent("Checked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyUserControl));

public event RoutedEventHandler Checked
{
    add { AddHandler(CheckedEvent, value); }
    remove { RemoveHandler(CheckedEvent, value); }
}

private void chkA_Checked(object sender, RoutedEventArgs e)
{
    RoutedEventArgs args = new RoutedEventArgs(MainWindow.CheckedEvent);
    RaiseEvent(args);
}

现在我可以看到“Checked”事件“冒泡”如下:

<Window x:Class Some.MainWindow xmlns:local="clr-namespace:Some" etc.>   
  <Grid>     
    <local:MyUserControl x:Name="MyUserControl_Main" **Checked="MyUserControl_Main_Checked"**></local:MyUserControl>   
  </Grid>
</Window>

感谢@Matt 的提示!

编辑3:

Matt的第一个答案是最好的方法,我有它“Checkbox”与“CheckBox”...将CheckBox.Checked添加到网格捕获事件:

I have a child control that has a checkbox and webbrowser:

<UserControl x:Class="Some.MyUserControl" etc.>
  <Grid>
    <CheckBox x:Name="chkA" Content="Analysis" Checked="chkA_Checked"></CheckBox>
    <WebBrowser Margin="0,30,0,0" Name="wbA"></WebBrowser>
  </Grid>
</UserControl>

I am putting this control in my MainWindow.xaml/.cs:

<Window x:Class Some.MainWindow xmlns:local="clr-namespace:Some" etc.>
  <Grid>
    <local:MyUserControl x:Name="MyUserControl_Main"></local:MyUserControl>
  </Grid>
</Window>

My question is how can my MainWindow know that the CheckBox (chkA) has been checked? So far only the actual user control knows it has been clicked? How can I expose the "Checked" event for my MainWindow to see? Or is there a better way?

I've searched the web, but can't seem to wrap my head around what I'm seeing.

Thank you in advance,

-newb

EDIT 1:

I am trying the following with no luck, but may be on the right track.

Within my MainWindow.xaml.cs I have added:

public static readonly RoutedEvent CheckedEvent = EventManager.RegisterRoutedEvent("Checked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyUserControl));

public event RoutedEventHandler Checked
{
    add { AddHandler(CheckedEvent, value); }
    remove { RemoveHandler(CheckedEvent, value); }
}

And within MyUserControl.xaml.cs I have added:

private void chkA_Checked(object sender, RoutedEventArgs e)
{
    RoutedEventArgs args = new RoutedEventArgs(MainWindow.CheckedEvent);
    RaiseEvent(args);
}

EDIT 2:

Moved previously mentioned code into MyUserControl.xaml.cs:

public static readonly RoutedEvent CheckedEvent = EventManager.RegisterRoutedEvent("Checked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyUserControl));

public event RoutedEventHandler Checked
{
    add { AddHandler(CheckedEvent, value); }
    remove { RemoveHandler(CheckedEvent, value); }
}

private void chkA_Checked(object sender, RoutedEventArgs e)
{
    RoutedEventArgs args = new RoutedEventArgs(MainWindow.CheckedEvent);
    RaiseEvent(args);
}

And now I am able to see the "Checked" event "Bubble" up as so:

<Window x:Class Some.MainWindow xmlns:local="clr-namespace:Some" etc.>   
  <Grid>     
    <local:MyUserControl x:Name="MyUserControl_Main" **Checked="MyUserControl_Main_Checked"**></local:MyUserControl>   
  </Grid>
</Window>

Thanks @Matt for the tip!

EDIT 3:

Matt's first answer is the best way to go, I had it "Checkbox" vs "CheckBox"... Adding CheckBox.Checked to the grid catches the event:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

妞丶爷亲个 2024-11-10 20:56:41

Checked 事件向上冒泡到父级并在那里捕获它。这就是路由事件的美妙之处!

<Grid CheckBox.Checked="CheckBox_Checked">
    <local:MyUserControl x:Name="MyUserControl_Main" />
</Grid>

Let the Checked event bubble up to the parent and catch it there. It's the beauty of routed events!

<Grid CheckBox.Checked="CheckBox_Checked">
    <local:MyUserControl x:Name="MyUserControl_Main" />
</Grid>
动听の歌 2024-11-10 20:56:41

您走在正确的轨道上,但您应该在 MyUserControl 中声明路由事件,而不是在 MainWindow 中...是引发事件的用户控件,而不是窗户。按照您的方式,您的控件显式依赖于 MainWindow,这是不好的做法,而且没有必要。

You're on the right track, but you should declare the routed event in MyUserControl, not in MainWindow... it's the user control that is raising the event, not the window. The way you're doing it, your control is explicitly depending on MainWindow, which is bad practice and not necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文