如何从主窗体中添加的模板用户控件中检测事件

时间:2014-06-02 23:38:49

标签: c# wpf xaml telerik

拥有一个在构造函数中获取id的用户控件模板SubCtrl 设置标签CounterLabelText并包含:

1个复选框
1个按钮
1 RadNumeric

<Grid Height="27" Width="602">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="533*" />
            <ColumnDefinition Width="44*" />
        </Grid.ColumnDefinitions>
        <Label                          Margin="26,0,492,0" Content="{Binding CounterLabelText}" />
        <CheckBox                       Height="16" HorizontalAlignment="Left" Margin="7,5,0,0"     Name="ChkBxOrder"              Width="21" VerticalAlignment="Top"  telerik:StyleManager.Theme="Vista" IsManipulationEnabled="True" />
        <!--<telerik:RadButton          Height="22" HorizontalAlignment="Left" Margin="343,1,0,0"   Name="ButtonDoSomething"       Width="58" VerticalAlignment="Top"  telerik:StyleManager.Theme="Vista" Content="Set Points" Click="ButtonDoSomething_Click" />-->
        <telerik:RadNumericUpDown       Height="18" HorizontalAlignment="Left" Margin="412,1,0,0"   Name="radx"                    Width="40" VerticalAlignment="Top"  IsInteger="True" telerik:StyleManager.Theme="Vista"/>
    </Grid>




public partial class SubCtrl : UserControl
{
    private string _counterLabelText;
    public string CounterLabelText
    {
        get
        {
            return _counterLabelText;
        }
        set
        {
            _counterLabelText = value;
            OnPropertyChanged("CounterLabelText");
        }
    }

    public SubCtrl(int id)
    {
        InitializeComponent();
        CounterLabelText = id.ToString();
        DataContext = this;
    }
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
}

用户控件是在主窗体内的ADD button上动态创建的,通过计数器,如

public partial class MainCtrl : UserControl
{
    int templateRowsCounter;

    //constructor and variables
    //...
    //...
    private void AddTemplate_Click(object sender, RoutedEventArgs e)
    {
        StackRefinement.Children.Add(new SubCtrl (++templateRowsCounter));
    }

    private void DelTemplate_Click(object sender, RoutedEventArgs e)
    {
        //how to remove it based on templateRowsCounter ???
    }

}

我有两个问题

  1. 如何使用DelTemplate_Click()添加删除上次添加的模板?
  2. SubCtrl包含复选框,按钮和radNumeric 我怎么知道何时必须调用ButtonDoSomething_Click()方法 当按ButtonDoSomething时,以及如何获取复选框和RadNumeric的状态,我的意思是如何检测事件?

1 个答案:

答案 0 :(得分:1)

<强>更新

SubCtrl类

  • 我添加了一个事件ButtonDoSomethingClicked
  • 向ButtonDoSomething.Click
  • 添加了事件处理程序
  • 在事件处理程序中调用了ButtonDoSomethingClicked

另外,当我将UserControl作为基类进行修改时,我更愿意使用DependencyProperty而不是INotifyPropertyChanged,所以也修改了CounterLabelText

public partial class SubCtrl : UserControl
{
    public event EventHandler ButtonDoSomethingClicked;

    public string CounterLabelText
    {
        get { return (string)GetValue(CounterLabelTextProperty); }
        set { SetValue(CounterLabelTextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CounterLabelText.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CounterLabelTextProperty =
        DependencyProperty.Register("CounterLabelText", typeof(string), typeof(SubCtrl), new PropertyMetadata(null));


    public SubCtrl(int id)
    {
        InitializeComponent();
        CounterLabelText = id.ToString();
        DataContext = this;
        ButtonDoSomething.Click += ButtonDoSomething_Click;
    }

    void ButtonDoSomething_Click(object sender, RoutedEventArgs e)
    {
        ButtonDoSomethingClicked.Invoke(this, EventArgs.Empty);
    }
}

MainCtrl的代码

  • 为ButtonDoSomethingClicked添加了事件处理程序
  • 已更新为使用templateRowsCounter进行删除。

班级代码

public partial class MainCtrl : UserControl
{
    int templateRowsCounter;

    private void AddTemplate_Click(object sender, RoutedEventArgs e)
    {
        SubCtrl sub = new SubCtrl(++templateRowsCounter);
        sub.ButtonDoSomethingClicked += sub_ButtonDoSomethingClicked;
        StackRefinement.Children.Add(sub);
    }

    private void DelTemplate_Click(object sender, RoutedEventArgs e)
    {
        SubCtrl sub = (SubCtrl)StackRefinement.Children[--templateRowsCounter];
        sub.ButtonDoSomethingClicked -= sub_ButtonDoSomethingClicked;
        StackRefinement.Children.Remove(sub);
    }

    void sub_ButtonDoSomethingClicked(object sender, EventArgs e)
    {
        //your do something logic
    }
}

所以这个样本传播了ButtonDoSomethingClicked,其余的也可以用同样的方式实现。当你无法修改代码时,ButtonBase.Click也很有用,也是一种比较通用的方法。

<强>前

这是问题1的快速解决方案

private void DelTemplate_Click(object sender, RoutedEventArgs e)
{
    //remove last added template, advisable to check if exists before deleting it
    StackRefinement.Children.RemoveAt(StackRefinement.Children.Count - 1);
}