2013-07-16 2 views
0

у меня есть пользовательский элемент управления с ресурсами, как показано ниже:МОФ - Контекстное меню - повторное использование статических ресурсов в рамках динамических ресурсов

<UserControl.Resources> 

    <Image x:Key="IconPrinter" Source="/PrintViewerWPF;component/Resources/Images/printer.png" /> 

    <MenuItem x:Key="PrintDoc" 
       Header="Print" 
       Click="PrintDoc_OnClick" 
       Icon="{StaticResource IconPrinter}" /> 

    <ContextMenu x:Key="MergedContextMenu"> 
     <StaticResource ResourceKey="PrintDoc"/> 
    </ContextMenu> 

    <ContextMenu x:Key="SingleContextMenu"> 
     <StaticResource ResourceKey="PrintDoc"/> 
    </ContextMenu> 

    <DataTemplate x:Key="mergedDocDisplayGrid"> 
     <StackPanel StackPanel.ContextMenu="{DynamicResource MergedContextMenu}" /> 
    </DataTemplate> 

    <DataTemplate x:Key="singleDocDisplayGrid"> 
     <StackPanel StackPanel.ContextMenu="{DynamicResource SingleContextMenu}" /> 
    </DataTemplate> 

</UserControl.Resources> 

The DataTemplate с используются в DevExpress FlowLayoutControl

В моем случае, у меня есть два элемента в моем FlowLayoutControl. Один с помощью шаблона mergedDocDisplayGrid, а другой с помощью singleDocDisplayGrid

данные отображаются правильно в шаблоне, и другие функции, такие как действия мыши и перетащить сбрасывания были успешно

реализована Отображение на одном из пунктов контекстного меню работает, но если я в дальнейшем попытаюсь показать контекстное меню снова на другом элементе я получаю следующее исключение:

Message - Add value to collection of type 'System.Windows.Controls.ItemCollection' threw an exception. 

Inner - Element already has a logical parent. It must be detached from the old parent before it is attached to a new one. 

Stack Trace 
    at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri) 
    at System.Windows.Markup.WpfXamlLoader.LoadDeferredContent(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings parentSettings, Uri baseUri) 
    at System.Windows.ResourceDictionary.CreateObject(KeyRecord key) 
    at System.Windows.ResourceDictionary.OnGettingValue(Object key, Object& value, Boolean& canCache) 
    at System.Windows.ResourceDictionary.OnGettingValuePrivate(Object key, Object& value, Boolean& canCache) 
    at System.Windows.ResourceDictionary.GetValueWithoutLock(Object key, Boolean& canCache) 
    at System.Windows.ResourceDictionary.GetValue(Object key, Boolean& canCache) 
    at System.Windows.DeferredResourceReference.GetValue(BaseValueSourceInternal valueSource) 
    at System.Windows.DependencyObject.GetEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, RequestFlags requests) 
    at System.Windows.DependencyObject.GetValueEntry(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, RequestFlags requests) 
    at System.Windows.DependencyObject.GetValue(DependencyProperty dp) 
    at System.Windows.Controls.ContextMenuService.GetContextMenu(DependencyObject element) 
    at System.Windows.Controls.ContextMenuService.ContextMenuIsEnabled(DependencyObject o) 
    at System.Windows.Controls.ContextMenuService.OnContextMenuOpening(Object sender, ContextMenuEventArgs e) 
    at System.Windows.Controls.ContextMenuEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget) 
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target) 
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs) 
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised) 
    at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args) 
    at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args) 
    at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted) 
    at System.Windows.Controls.PopupControlService.RaiseContextMenuOpeningEvent(IInputElement source, Double x, Double y, Boolean userInitiated) 
    at System.Windows.Controls.PopupControlService.ProcessMouseUp(Object sender, MouseButtonEventArgs e) 
    at System.Windows.Controls.PopupControlService.OnPostProcessInput(Object sender, ProcessInputEventArgs e) 
    at System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(ProcessInputEventHandler postProcessInput, ProcessInputEventArgs processInputEventArgs) 
    at System.Windows.Input.InputManager.ProcessStagingArea() 
    at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input) 
    at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport) 
    at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel) 
    at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
    at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) 
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
    at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
    at System.Windows.Forms.NativeWindow.DefWndProc(Message& m) 
    at System.Windows.Forms.NativeWindow.WndProc(Message& m) 
    at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
    at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) 
    at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) 
    at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) 
    at System.Windows.Threading.Dispatcher.Run() 
    at System.Windows.Application.RunDispatcher(Object ignore) 
    at System.Windows.Application.RunInternal(Window window) 
    at System.Windows.Application.Run(Window window) 
    at System.Windows.Application.Run() 
    at Camps.PrintViewerWPF.App.Main() in C:\Dev\Camps.Printing2\trunk\Camps.Printing2\Presentation\Camps.PrintViewerWPF\obj\x86\Release\App.g.cs:line 0 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 

внутреннее исключение само за себя, и я уверен, что я смог бы решить эту проблему в коде позади, как когда-либо, я чувствую, что в XAML должно быть сделано это правильно, потому что для меня важно повторное использование пунктов меню.

Любая помощь будет принята с благодарностью! Спасибо

ответ

5

Попробуйте StaticResourceExtension и x:Shared="false".

<MenuItem x:Key="PrintDoc" 
      x:Shared="false"    
      Header="Print" 
      Click="PrintDoc_OnClick" 
      Icon="{StaticResource IconPrinter}" /> 

<ContextMenu x:Key="MergedContextMenu"> 
    <StaticResourceExtension ResourceKey="PrintDoc" /> 
</ContextMenu> 

Проверить this link.