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));
Итог, как лучше всего:
- Подражать xaml: SampleAggregator = "{Binding SampleAggregator, ElementName = AudioPlayerMenu}"(который работает) в пользовательском коде TheRecorder?(И на самом деле это работает!)
- Предоставить пользовательский пункт меню в пользовательском меню?(Тем самым избегая всей вещи xaml).
Заранее благодарен за любые предложения или помощь.