How to Access a Button present inside a Custom Control, from the implementing page?

你。 提交于 2019-12-31 02:35:31

问题


I have my generic.xaml containing the following code:

<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>

Now on applyTemplate , I am accessing the controls like below:

 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);
            };

        }

Now I want acccess the nextBtn, in the page where I am implementing like

CustomVideoControl myVControl=new CustomVideoControl();

This will create the instance of the control, but I want to do something on the click of next and previous button, thta is present inside the CustomVideoControl in generic.xaml. Any help will be greatly appreciated.

Thanks, Subhen


回答1:


You just need to add a couple of events to your Control.

 public event EventHandler MovedPrevious
 public event EventHandler MovedNext

Now this are typically implemented like this:-

 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);   
 }

Now in your existing click events:-

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);
};

Now in your consuming code you can do this sort of thing:-

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



回答2:


Sorry, but you're doing it wrong. There's no good reason why you should have a reference to elements inside a DataTemplate IMO. [...Read more at this forum post...]




回答3:


You could create public events in your custom control, something like NextButtonClicked and PreviousButtonClicked.




回答4:


I have a feeling, that you're trying to mimic EventSetter behaviour. If I'm right, please just take a look on this simple example:

    <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>

This code assigns your custom event to some text block's regular action directly from XAML (you don't have to pollute your code behind with accessing controls' properties).

I hope this is helpful, but if not, please give me a shout.

Edit:

Sorry for not being perfectly clear (this was just a quickly pasted code snippet). Please have a look on a complete example:

Styles for your next/previous buttons:

<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>

Code behind:

 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);   
        }
     }

Since now on you can access OnMovedNext and OnMovedPrevious directly from your control's handling conrol/whatever just as Anthony posted.

Sorry if my previous answer was confusing, but it supposed to be just an inspiration what to do :)

Edit:

I haven't noticed that this regards only Silverlight for which I apologize :) But, it works perfectly for WPF if you wish to try.



来源:https://stackoverflow.com/questions/2690177/how-to-access-a-button-present-inside-a-custom-control-from-the-implementing-pa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!