简体   繁体   English

如何获取发送路由事件的控件的父控件的列索引?

[英]How do I get the column index of parent control of control that sent the routed event?

I have a UserControl on my form with a Button that when clicked, adds another instance of the UserControl or a different UserControl in a new row or column. 我的UserControl上有一个带ButtonUserControl ,当单击该Button时,它会在新行或列中添加另一个UserControl实例或另一个UserControl What I'm trying to do is when the Button is clicked, find out what column the UserControl containing the Button is in, and then add the new UserControl to that same column. 我想做的是单击“ Button ,找出包含“ ButtonUserControl在哪一列,然后将新的UserControl添加到同一列。 The code for this is below: 此代码如下:

        ++rowCount;
        int currentColumn = Grid.GetColumn(e.Source as UIElement);
        AnswerNode answerNode = new AnswerNode();
        answerNode.buttonAddQuestionNode.MouseLeftButtonDown += AddQuestionNode_DifferentLevelEvent;
        answerNode.Margin = new Thickness(0, 5, 0, 5);
        RowDefinition gridRowNew = new RowDefinition();
        gridRowNew.Height = new GridLength(70);
        Grid.SetRow(answerNode, rowCount);
        Grid.SetColumn(answerNode, currentColumn);
        MainGrid.RowDefinitions.Add(gridRowNew);
        MainGrid.Children.Add(answerNode);

The problem I'm running into is that getting the column index for e.Source is resulting in the index of the button within the UserControl — in this case 1 — and not the column index of the UserControl itself. 我遇到的问题是获取e.Source的列索引会导致UserControl按钮的索引(在本例中为1 ,而不是UserControl本身的列索引。 How would I access the column index of the UserControl that is the parent of the Button which was clicked? 如何访问被单击的Button的父级UserControl的列索引?

Without a good, minimal , complete code example that clearly illustrates the question, showing exactly what you've tried and how you want the event handling to work, it's difficult to know for sure what the best answer would be. 如果没有一个很好的, 最少的完整的代码示例来清楚地说明问题,准确显示您尝试过的内容以及希望事件处理如何工作,那么很难确定最佳答案是什么。 That said, from what little code you've provided and your problem description, it sounds like you have subscribed to the event in the wrong control object. 就是说,从您提供的很少的代码和问题描述中,听起来好像您已在错误的控制对象中订阅了该事件。 Specifically, you have declared your event handler in the Button object directly, rather than subscribing to the Button.Click event in the UserControl . 具体来说,您已经直接在Button对象中声明了事件处理程序,而不是在UserControl订阅了Button.Click事件。

For a routed event, you can always get the original source of the event, ie the control where the event was initially signaled via the RoutedEventArgs.OriginalSource property. 对于路由事件,您始终可以获取事件的原始来源,即最初通过RoutedEventArgs.OriginalSource属性发出信号的控件。 The RoutedEventArgs.Source property in turn will provide the reference to the control object to which the event has been routed and is currently handling the event. RoutedEventArgs.Source属性将提供对事件已路由到且当前正在处理事件的控制对象的引用。 If you want to handle the event as seen by the UserControl object, then you need to subscribe to the event from the UserControl object, not the Button object. 如果要处理UserControl对象看到的事件,则需要从UserControl对象而不是Button对象预订事件。

Here is a short, complete code example that illustrates the basic technique: 这是一个简短的完整代码示例,它说明了基本技术:

XAML: XAML:

UserControl1.xaml UserControl1.xaml

<UserControl x:Class="TestSO33441926RoutedEvent.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <TextBlock Text="Click here: "/>
    <Button x:Name="button1" Content="Click me!" Grid.Column="1"
            HorizontalAlignment="Left" VerticalAlignment="Top"
            Click="Button_Click"/>
  </Grid>
</UserControl>

MainWindow.xaml MainWindow.xaml

<Window x:Class="TestSO33441926RoutedEvent.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:TestSO33441926RoutedEvent"
        Title="MainWindow" Height="350" Width="525">
  <Grid x:Name="grid1">
    <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <TextBlock Text="MainWindow column 1"/>
    <TextBlock Text="MainWindow column 2" Grid.Column="1"/>
    <l:UserControl1 x:Name="userControl1" Grid.Column="2"
                    Button.Click="UserControl1_Click"/>
  </Grid>
</Window>

C#: C#:

UserControl1.xaml.cs UserControl1.xaml.cs

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        App.ReportClick((FrameworkElement)e.Source);
    }
}

MainWindow.xaml.cs MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void UserControl1_Click(object sender, RoutedEventArgs e)
    {
        App.ReportClick((FrameworkElement)e.Source);
    }
}

App.xaml.cs App.xaml.cs

public partial class App : Application
{
    public static void ReportClick(
        FrameworkElement frameworkElement, [CallerMemberName]string callerName = null)
    {
        MessageBox.Show(
            "Caller name: \"" + callerName + "\"\n" +
            "Sender name: \"" + frameworkElement.Name + "\"\n" +
            "Sender column: " + Grid.GetColumn(frameworkElement));
    }
}

Since neither event handler sets RoutedEventArgs.Handled to true , the event will be sent to each handler in turn, starting with the original source of the event and moving up the visual object graph to each parent in turn. 由于这两个事件处理程序均未将RoutedEventArgs.Handled设置为true ,因此该事件将依次发送到每个处理程序,从事件的原始来源开始,然后将可视对象图向上移动到每个父级。

As such, you can see that when the ReportClick() method is called by each event handler, the e.Source object is different in each event handler, depending on where that handler was subscribed. 这样,您可以看到每个事件处理程序ReportClick()方法时,每个事件处理程序中的e.Source对象都不同,这取决于该处理程序的预订位置。

For your own question, the key is here, in the MainWindow.xaml source code: 对于您自己的问题,关键在MainWindow.xaml源代码中:

    <l:UserControl1 x:Name="userControl1" Grid.Column="2"
                    Button.Click="UserControl1_Click"/>

Note that the Button.Click event is the one being subscribed, but that the code is subscribing from the UserControl1 object . 请注意, Button.Click事件是要订阅的事件,但是该代码是UserControl1对象订阅 This has the result that the event handler void UserControl1_Click(object, RoutedEventArgs) is called with the UserControl1 object as the sender and source of the event. 结果是调用事件处理程序void UserControl1_Click(object, RoutedEventArgs) ,将UserControl1对象作为事件的发送者和源。

Thus, when the column index of the sender of the event is retrieved by calling Grid.GetColumn(UIElement) , the column index of the UserControl1 object is returned, not the column index of the original source of the event (ie the Button object that was actually clicked). 因此,当通过调用Grid.GetColumn(UIElement)检索事件发送者的列索引时,将返回UserControl1对象的列索引,而不是事件原始源(即Button对象)的列索引。实际上被点击了)。


As an aside: in the bit of code your posts shows, there seems to be a fair amount of code-behind that is probably better-implemented as XAML declarations. 顺便说一句:在您的帖子中所显示的一些代码中,似乎有大量的代码隐藏可以更好地实现为XAML声明。 Naturally, just about anything you can do in XAML, you can also accomplish in code-behind. 自然,几乎可以在XAML中完成的任何事情,也可以在代码隐藏中完成。 But that doesn't mean it's a good idea. 但这并不意味着它是一个好主意。 Addressing that defect in your code is not likely to relate directly to the question you're asking, nor would changing the implementation in that way fix the problem. 解决您的代码中的缺陷不太可能与您要提出的问题直接相关,也不会以这种方式更改实现来解决问题。 But you should definitely consider seriously following the WPF/XAML paradigm more closely and put as much of your implementation in XAML as you can. 但是,您绝对应该考虑更严格地遵循WPF / XAML范例,并尽可能多地在XAML中放置您的实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM