如何从实现页面访问自定义控件内的按钮?

时间:2010-04-22 11:04:56

标签: c# silverlight custom-controls

我的generic.xaml包含以下代码:

<ControlTemplate TargetType="local:customVideoControl">

   <Grid>

          <Grid.RowDefinitions>
                     <RowDefinition Height="600"/>
                     <RowDefinition Height="200"/>
          </Grid.RowDefinitions>

           <Grid.ColumnDefinitions>
                       <ColumnDefinition Width="200"/>
                       <ColumnDefinition Width="200"/>
                       <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>

                    <MediaElement x:Name="customMediaPlayer" Source="{TemplateBinding CustomMediaSource}"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center"
                                   Height="{TemplateBinding Height}"
                                   Width="{TemplateBinding Width}"
                                  Grid.Row="0" Grid.ColumnSpan="3"
                                  />

                    <ToggleButton x:Name="playPauseBtn" Height="50" Width="50" Content="Pause" Grid.Row="1" Grid.Column="0"/>
                     <Button x:Name="prevBtn" Height="50" Width="50" Content="Prev" Grid.Row="1" Grid.Column="1"/>
                     <Button x:Name="nextBtn" Height="50" Width="50" Content="Next" Grid.Row="1" Grid.Column="2"/>

   </Grid>
</ControlTemplate>

现在在applyTemplate上,我正在访问如下控件:

 public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            ToggleButton playPauseBtn = GetTemplateChild("playPauseBtn") as ToggleButton;

            Button prevBtn= GetTemplateChild("prevBtn") as Button;
            Button nextBtn = GetTemplateChild("nextBtn") as Button;
            MediaElement customMediaPlayer = GetTemplateChild("customMediaPlayer") as MediaElement;

            playPauseBtn.Checked += (obj, Args) =>
                {
                    customMediaPlayer.Pause();
                    playPauseBtn.Content = "Play";
                };

            playPauseBtn.Unchecked += (obj, Args) =>
                {
                    customMediaPlayer.Play();
                    playPauseBtn.Content = "Pause";
                };



            nextBtn.Click += (obj, Args) =>
                {
                    customMediaPlayer.Source=new Uri(CustomMediaSource.ToString(),UriKind.RelativeOrAbsolute);

                };

            prevBtn.Click += (obj, Args) =>
            {
                customMediaPlayer.Source = new Uri(CustomMediaSource.ToString(), UriKind.RelativeOrAbsolute);
            };

        }

现在我希望在我正在实现的页面中使用nextBtn,如

CustomVideoControl myVControl=new CustomVideoControl();

这将创建控件的实例,但我想在点击时执行某些操作 下一个和上一个按钮,thta存在于generic.xaml中的CustomVideoControl中。任何帮助将不胜感激。

谢谢, Subhen

4 个答案:

答案 0 :(得分:1)

您只需向控件添加一些事件即可。

 public event EventHandler MovedPrevious
 public event EventHandler MovedNext

现在通常这样实现: -

 protected virtual void OnMovedPrevious(EventArgs e)
 {
   var handler = MovedPrevious;
   if (handler != null)
     handler(this, e);   
 }

 protected virtual void OnMovedNext(EventArgs e)
 {
   var handler = MovedNext;
   if (handler != null)
     handler(this, e);   
 }

现在在您现有的点击事件中: -

nextBtn.Click += (obj, Args) =>
{
  customMediaPlayer.Source=new Uri(CustomMediaSource.ToString(),UriKind.RelativeOrAbsolute);  //No idea what this doing
  OnMovedNext(EventArgs.Empty);
};

prevBtn.Click += (obj, Args) =>
{
  customMediaPlayer.Source = new Uri(CustomMediaSource.ToString(), UriKind.RelativeOrAbsolute); //No idea what this is doing either
  OnMovedPrevious(EventArgs.Empty);
};

现在,在您的消费代码中,您可以执行以下操作: -

CustomVideoControl myVControl=new CustomVideoControl();
myVControl.MovedNext += (s, args) => { /* deal with next */ };
myVControl.MovedPrevious += (s, args) => { /* deal with previous */ };

答案 1 :(得分:1)

抱歉,但你做错了。 没有充分的理由说明为什么要引用DataTemplate IMO中的元素。 [... Read more at this forum post ...

答案 2 :(得分:0)

您可以在自定义控件中创建公共事件,例如NextButtonClicked和PreviousButtonClicked。

答案 3 :(得分:0)

我有一种感觉,你正试图模仿EventSetter的行为。如果我是对的,请看一下这个简单的例子:

    <Style TargetType="{x:Type Button}" x:Key="SomeID">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Cursor" Value="Hand"></Setter>
                <Setter Property="FontWeight" Value="Bold"></Setter>
            </Trigger>
        </Style.Triggers>
        <EventSetter Event="MouseUp" Handler="DoSomething_Click"></EventSetter>
    </Style>

此代码直接从XAML为您的自定义事件分配一些文本块的常规操作(您不必通过访问控件的属性来污染您的代码)。

我希望这有用,但如果没有,请给我一个大喊。

修改

很抱歉没有完全清楚(这只是一个快速粘贴的代码段)。请看一个完整的例子:

下一个/上一个按钮的样式:

<Style TargetType="{x:Type Button}" x:Key="PreviousButtonstyle">
    <EventSetter Event="Click" Handler="OnMovedPrevious"></EventSetter>
</Style>

<Style TargetType="{x:Type Button}" x:Key="NextButtonstyle">
    <EventSetter Event="Click" Handler="OnMovedNext"></EventSetter>
</Style>

代码背后:

 public event EventHandler MovedPrevious;
 public event EventHandler MovedNext;

     protected void OnMovedPrevious(object sender, RoutedEventArgs e)
     {
       if (MovedPrevious != null)
       {
          MovedPrevious(this, e);   
       }
     }

     protected void OnMovedNext(object sender, RoutedEventArgs e)
     {
        if (MovedNext != null)
        {
           MovedNext(this, e);   
        }
     }

从现在开始,您可以直接从您的控件处理控件/安东尼发布的内容中访问 OnMovedNext OnMovedPrevious

很抱歉,如果我之前的回答令人困惑,但它应该只是一个灵感,该怎么办:)

修改

我没有注意到这只涉及我向其道歉的Silverlight :)但是,如果您想尝试,它对WPF非常有用。