views:

121

answers:

4

Hi,

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

A: 

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

Henrik Söderlund
Could you please explain
Subhen
What I meant was exactly the same as the answer AnthonyWJones has already posted.
Henrik Söderlund
A: 

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.

Piotr Justyna
I tried adding this to my generic.xaml in silverlight, seems invalid Thanks
Subhen
It is perfecly valid for a textblock :) Post some code and I'll see what I can do.
Piotr Justyna
Sorry, I changed TextBlock to Button, but it should definitely work fine.
Piotr Justyna
This is entirely inappropriate for the problem at hand.
AnthonyWJones
I don't think so. Sorry for a "generic" xaml, but I just pasted it from one of my projects to inspire you with the idea. Anthony, please note, that you're doing exactly the same thing, only in code behind. Please see my updated answer to see my point of view.
Piotr Justyna
Have you tried this in Silverlight? Silverlight doesn't have an `EventSetter` class.
AnthonyWJones
You're right. I will modify my answer.
Piotr Justyna
+1  A: 

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 */ };
AnthonyWJones
Please update your code, because right now it's invalid and won't compile. OnMovedNext and OnMovedPrevious should have return type.
Piotr Justyna
@Piotr: Well spotted
AnthonyWJones
My Highest gratitude for you guyz, I am not sure if m doing something illegeal with respect to CLR or something but this is what I need on my project now.Thanx a ton agn.
Subhen
+1  A: 

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

JustinAngel