Не удается инициализировать свойство зависимости, когда оно связано с кодом в пользовательском элементе управления - PullRequest
0 голосов
/ 27 октября 2018

WPF

Можно ли это сделать без использования прикрепленного поведения?

Я поместил весь свой исполняемый код в пользовательское меню AudioPlayermenu.

В пользовательском меню естьпользовательский пункт меню, TheRecorder, который используется для отображения движущейся волны многоугольника.Все работает хорошо, когда основной xaml explicity связывает MenuItem, TheRecorder, с Menu, AudioPlayerMenu:

например, SampleAggregator = "{Binding SampleAggregator, ElementName = AudioPlayerMenu }"

 <w:AudioPlayerMenu x:Name="AudioPlayerMenu" EncounterRecid="{Binding EncounterRecid}">
                <StackPanel Orientation="Horizontal"> 
                    Value="{Binding CurrentInputLevel, RelativeSource={RelativeSource AncestorType={x:Type Menu}, AncestorLevel=1}}" -->
                    <w:PeakMeter  Value="{Binding CurrentInputLevel, ElementName=AudioPlayerMenu}"   
                                  Width="150"/>
                    <w:AudioVideoSlider/>
                </StackPanel>

                <MenuItem>
                    <MenuItem.Header>
                        <Grid>
                            <Viewbox Stretch="Fill">
                                <Path Fill="#ff951c1f" Data="F1 M 0 0 L 16 16 L 32 0 Z" />
                            </Viewbox>
                        </Grid>
                    </MenuItem.Header>
                    <w:TheRecorder StaysOpenOnClick="True"
                                   SampleAggregator ="{Binding SampleAggregator, ElementName=AudioPlayerMenu}"
                                   SpeakerVolume ="{Binding SpeakerVolume, ElementName=AudioPlayerMenu, Mode=TwoWay}"
                                   CaptureDevices="{Binding CaptureDevices, ElementName=AudioPlayerMenu}"
                                   SelectedDevice="{Binding SelectedDevice, ElementName=AudioPlayerMenu}"
                                   SampleRate="{Binding SampleRate, ElementName=AudioPlayerMenu}"
                                   Recordings="{Binding Recordings, ElementName=AudioPlayerMenu}"
                                   RecordingSelectedItem="{Binding RecordingSelectedItem, ElementName=AudioPlayerMenu, Mode=TwoWay}" 
                                   RecordedTime="{Binding RecordedTime, ElementName=AudioPlayerMenu}"  
                                   CurrentTrackLength="{Binding CurrentTrackLength, ElementName=AudioPlayerMenu}" 
                                   CurrentTrackPosition="{Binding CurrentTrackPosition, ElementName=AudioPlayerMenu, Mode=TwoWay}" 
                                   CurrentInputLevel="{Binding CurrentInputLevel, ElementName=AudioPlayerMenu}" />
                </MenuItem>

C #

#region [SampleAggregator]
        public SampleAggregator SampleAggregator
        {
            get { return (SampleAggregator)GetValue(SampleAggregatorProperty); }
            set { SetValue(SampleAggregatorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SampleAggregator.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SampleAggregatorProperty =
            DependencyProperty.Register("SampleAggregator", typeof(SampleAggregator), typeof(TheRecorder), new PropertyMetadata(null));
        #endregion

Как показано выше, у меня есть много свойств, связанных в xaml.Поскольку TheRecorder полностью зависит от меню AudioPlayerMenu, мне кажется, что имеет больше смысла полностью переместить TheRecorder в меню.В качестве первого шага я пытаюсь переместить все привязки свойств из xaml в сам пользовательский элемент управления.ВСЕ мои попытки провалились!

В конечном счете, привязка, кажется, правильно разрешена, но я не могу заставить SampleAggregator на TheRecorder инициализироваться, когда он установлен в Меню.Это остается нулевым в TheRecorder.(Я также попытался переместить привязку из OnApplyTemplate () к событию Loaded с теми же результатами).

Вот что я пробовал:

В TheRecorder (пользовательский элемент управления):

 public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            RecordingProgressBar = GetTemplateChild(PART_RecordingProgressBar) as Slider;

            RecordingProgressBar.PreviewMouseDown += RecordingProgressBar_PreviewMouseDown;
            RecordingProgressBar.PreviewMouseUp += RecordingProgressBar_PreviewMouseUp;

            //  SampleAggregator ="{Binding SampleAggregator, ElementName=AudioPlayerMenu}"
            var bindingSampleAggregator = new Binding
            {
                RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(AudioPlayerMenu), 1),
                Path = new PropertyPath(SampleAggregatorProperty)             
            };
            // The Target of the binding is this, TheRecorder.
            BindingOperations.SetBinding(target: this, dp: SampleAggregatorProperty, binding: bindingSampleAggregator);
        }

Привязка, кажется, правильно разрешена, но SampleAggregator никогда не инициализируется из AudioPlayerMenu.В AudioPlayerMenu у меня есть:

 private void AudioPlayerMenu_Loaded(object sender, RoutedEventArgs e)
        {
            SpeakerVolume = 100;

            SampleAggregator = new SampleAggregator();
        }

 public SampleAggregator SampleAggregator
        {
            get { return (SampleAggregator)GetValue(SampleAggregatorProperty); }
            set { SetValue(SampleAggregatorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SampleAggregator.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SampleAggregatorProperty =
            DependencyProperty.Register("SampleAggregator", typeof(SampleAggregator), typeof(AudioPlayerMenu));

Итог, как лучше всего:

  1. Подражать xaml: SampleAggregator = "{Binding SampleAggregator, ElementName = AudioPlayerMenu}"(который работает) в пользовательском коде TheRecorder?(И на самом деле это работает!)
  2. Предоставить пользовательский пункт меню в пользовательском меню?(Тем самым избегая всей вещи xaml).

Заранее благодарен за любые предложения или помощь.

...