从自定义控件中的代码绑定时,无法初始化依赖项属性

时间:2018-10-27 18:44:08

标签: c# wpf xaml custom-controls

WPF

可以在不使用附加行为的情况下完成此操作吗?

我已将所有可执行代码置于自定义菜单AudioPlayermenu中。

自定义菜单有一个自定义菜单项TheRecorder,用于显示移动的多边形波。当主xaml明确地将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中移出到自定义控件本身中。我所有的尝试都失败了!

最终,绑定似乎已正确解决,但是当在菜单中进行设置时,我无法让TheRecorder上的SampleAggregator初始化。在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);
        }

绑定似乎已正确解决,但从未从AudioPlayerMenu初始化SampleAggregator。在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:TheRecorder的自定义代码中的SampleAggregator =“ {Binding SampleAggregator,ElementName = AudioPlayerMenu}”(有效)吗? (实际上起作用了!)
  2. 在自定义菜单中提供自定义菜单项吗? (从而避免了整个xaml的事情。)

预先感谢您的任何建议或帮助。

0 个答案:

没有答案