Как получить доступ к кнопке, представленной внутри пользовательского элемента управления, со страницы реализации? - PullRequest
2 голосов
/ 22 апреля 2010

У меня есть мой файл 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();

Это создаст экземпляр элемента управления, но я хочу сделать что-то по щелчку Следующая и предыдущая кнопка присутствует в CustomVideoControl в generic.xaml. Любая помощь будет принята с благодарностью.

Спасибо, Subhen

Ответы [ 4 ]

1 голос
/ 22 апреля 2010

Извините, но вы делаете это неправильно.Нет веской причины, по которой у вас должна быть ссылка на элементы внутри IMO DataTemplate.[... Читать дальше на этом форуме ...]

1 голос
/ 22 апреля 2010

Вам просто нужно добавить пару событий в ваш элемент управления.

 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 */ };
0 голосов
/ 22 апреля 2010

У меня такое ощущение, что вы пытаетесь имитировать поведение 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 (вам не нужно загрязнять свой код с помощью доступа к свойствам элементов управления).

Я надеюсь, что это полезно, но если нет, пожалуйста, напишите мне.

Edit:

Извините, что не совсем ясно (это был просто быстро вставленный фрагмент кода). Пожалуйста, посмотрите на полный пример:

Стили для ваших следующих / предыдущих кнопок:

<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 непосредственно из консоли управления вашего элемента управления / чего угодно, как только что написал Энтони.

Извините, если мой предыдущий ответ сбивал с толку, но это должно было быть просто вдохновением, что делать :)

Edit:

Я не заметил, что это касается только Silverlight, за который я прошу прощения :) Но он отлично работает для WPF, если вы хотите попробовать.

0 голосов
/ 22 апреля 2010

Вы можете создавать публичные события в своем пользовательском элементе управления, например NextButtonClicked и PreviousButtonClicked.

...