How do I access a button that is inside a custom control from the implementation page?

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 to acccess nextBtn, in the page where I am implementing like

CustomVideoControl myVControl=new CustomVideoControl();

      

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

Thanks, Subhen

+2


a source to share


4 answers


You just need to add some events to your control.

 public event EventHandler MovedPrevious
 public event EventHandler MovedNext

      

Now it is usually done 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 consumer code, you can do things like this: -

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

      

+1


a source


Sorry, but you are doing it wrong. There is no good reason why you should have a reference to the elements inside the DataTemplate IMO. [... Read more on this forum ...]



+1


a source


You can create public events in your custom control such as NextButtonClicked and PreviousButtonClicked.

0


a source


I have a feeling that you are trying to mimic the behavior of the EventSetter. If I'm right, just take a look at 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 regular text block action directly from XAML (you don't need to pollute your code with access to control properties).

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

Edit:

Sorry for the misunderstanding (this was just a copied piece of code). Please see the full 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);   
        }
     }

      

From now on, you can access OnMovedNext and OnMovedPrevious directly from your control processing control / no matter how Anthony posted.

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

Edit:

I didn't notice that this is only for Silverlight, which I am sorry for :) But it works great for WPF if you want to try it out.

0


a source







All Articles