Добавить новые элементы контекстного меню в WindowsFormsHost, который имеет контекстное меню по умолчанию в WPF

Мы используем элементы управления ActiveX или формы Windows, которые не имеют эквивалентов WPF, поэтому, естественно, мы используем WindowsFormsHost для размещения этих элементов управления. Обычно мы делаем из него UserControl с некоторыми общими элементами управления, такими как кнопка, для реализации общих функций. Один фрагмент кода xaml выглядит примерно так:

<WindowsFormsHost Name="windowsFormsHost1" >   
    <WindowsFormsHost.ContextMenu>
        <ContextMenu>                    
            <MenuItem Header="_Test1" />
        </ContextMenu>                    
    </WindowsFormsHost.ContextMenu>

    <AxOWC:AxPivotTable x:Name="pivotTable" />        
</WindowsFormsHost>        
....

AxPivotTable - это элемент управления OWC (офисный веб-компонент). В другом UserControl мы добавляем ReportViewer внутри WindowsFormsHost. Обратите внимание, что обычно AxPivotTable или ReportViewer имеют свое контекстное меню по умолчанию даже без добавленного мной элемента ContextMenu.

Пока что мое настроенное ContextMenu еще не отображается (по-прежнему отображается значение по умолчанию). Благодаря этому вопросу, я понял, что мне все еще нужно зафиксировать событие опускания мыши в код программной части и набор

windowsFormsHost1.ContextMenu.IsOpen = True

чтобы показать контекстное меню (хотя и странно).

Теперь моя проблема в том, что здесь сейчас только это Контекстное меню Test1. Контекстное меню по умолчанию больше не отображается. Как я уже упоминал, мы хотим добавить настраиваемые поверх контекстных меню по умолчанию.


person tete    schedule 14.03.2013    source источник
comment
Вы можете нырнуть в свой windowsFormsHost1, чтобы получить ContextMenu объект? чтобы ты мог сделать _yourContextMenu_.Items.Add(newMenuItem)   -  person WiiMaxx    schedule 14.03.2013
comment
@WiiMaxx, на самом деле я не понимаю этого. В моем обработчике событий, в котором я установил IsOpen = True, я вижу, что ContextMenu на самом деле содержит только мои настроенные элементы, а не меню по умолчанию, предоставляемое самим элементом управления. Поэтому я не знаю, как мне получить эти меню по умолчанию, поэтому я не могу их добавить (поскольку элемент управления отсутствует в сборках WPF, я даже не знаю, могу ли я просто использовать Items.Add, чтобы добавить их без преобразования). Другими словами, мой настроенный CM перезапишет значения по умолчанию, поскольку они находятся на разных уровнях, и только если у меня нет настроенного, по умолчанию будет отображаться.   -  person tete    schedule 14.03.2013


Ответы (1)


это будет мое рабочее «Решение» для вашего примера выше, я не знаю, нужно ли вам это также для дочерних элементов из вашего WindowsFormsHost. Надеюсь, что это поможет вам

XAML

<Window x:Class="tete.MainWindow"
        xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
        xmlns="http://schemas.microsoft.com/netfx/2009/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms">
    <Grid>
        <av:WindowsFormsHost Name="myWFH">
            <wf:ComboBox Name="myCBox">
            <wf:ComboBox.ContextMenu>
                <wf:ContextMenu>
                    <wf:ContextMenu.MenuItems>
                        <wf:MenuItem Text="somet"/>
                    </wf:ContextMenu.MenuItems>
                </wf:ContextMenu>
            </wf:ComboBox.ContextMenu>
        </wf:ComboBox>

    </Grid>
</Window>

Код позади

using System.Windows;
using System.Windows.Controls;

namespace tete
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

        var child = myWFH.Child as System.Windows.Forms.ComboBox;
        child.ContextMenu.MenuItems.Add(new System.Windows.Forms.MenuItem("my new menuitem"));
        }
    }
}

РЕДАКТИРОВАТЬ, надеюсь, теперь это соответствует вашим потребностям :) и я правильно понимаю, что вы хотите сделать.

person WiiMaxx    schedule 14.03.2013
comment
спасибо за ответ, но какую проблему вы пытаетесь решить с помощью этого кода? Возможно, я не ясно сформулировал свой вопрос. AxOWC: AxPivotTable (и другие элементы управления WinForms, которые мы оборачиваем внутри WindowsFormsHost) имеет свое ContextMenu по умолчанию, которое имеет тип System.Windows.Forms.ContextMenu, а не тип WPF. Но теперь я хочу, чтобы мои настраиваемые элементы контекстного меню сосуществовали с элементами по умолчанию, чтобы у пользователя было расширенное контекстное меню. Но с моим кодом из вопроса настраиваемое меню будет перезаписывать / затенять контекстное меню по умолчанию, чего я не хочу. - person tete; 14.03.2013
comment
о, похоже, я скучаю по этой части: о) я немного покопаюсь в этом - person WiiMaxx; 14.03.2013
comment
Да спасибо. Несколько слов о результатах: я использую myWFH.ContextMenu.IsOpen = true в обработчике события нажатия мыши, и вы делаете это в конструкторе. Ваш код в основном делает то же, что и мой пост, за исключением одного: если я запустил ваш код, настраиваемое контекстное меню появится один раз при создании UserControl / Window, по-прежнему затеняя значение по умолчанию, а позже, когда я щелкну правой кнопкой мыши по умолчанию контекстное меню снова отображается, затеняя настраиваемое. Напротив, мой код всегда затеняет контекстное меню по умолчанию. Ни один из способов не дает желаемого результата - person tete; 14.03.2013
comment
@tete, надеюсь, теперь это то, что вам нужно, если оно не подходит для облака, скажите, пожалуйста, какая сборка AxOWC, чтобы я мог копнуть глубже;) - person WiiMaxx; 14.03.2013
comment
Большое вам спасибо за вашу помощь. У меня все еще есть проблема с элементами управления, но я вернусь к вам позже. - person tete; 14.03.2013
comment
WiiMaxx, до сих пор не могу понять. Ваш пример отличается по крайней мере в одном факте: wf: ComboBox в любом случае не имеет интегрированного контекстного меню. Поэтому, когда вы добавляете один элемент в xaml и другие в код программной части, все находится под вашим контролем, и вы точно знаете, что они будут отображаться вместе. Но элементы управления, которые я использую, например Microsoft.Reporting.WinForms.ReportViewer, сам элемент управления имеет контекстное меню, и действительно загадочно, где я могу найти этот объект контекстного меню и добавить туда свои настройки. Например, если я буду следовать вашей программе, чтобы иметь Dim child = windowsFormsHost1.Child. - person tete; 15.03.2013
comment
Я вижу, что child.ContextMenu.MenuItems имеет фактически нулевую коллекцию счетчиков, что означает, что контекстное меню по умолчанию не существует на этом уровне. И поэтому добавление нового пункта меню на этом уровне не может привести к тому, что он появится в контекстном меню по умолчанию. Фактически, тот, который я добавил в MenuItems, вообще не будет отображаться, по-прежнему отображается только контекстное меню по умолчанию, которое я АБСОЛЮТНО не знаю, откуда оно взялось. - person tete; 15.03.2013
comment
@tete после обеда я посмотрю на это, может быть, я смогу это понять :) - person WiiMaxx; 15.03.2013
comment
@tete ok, я мог бы сузить вашу проблему (в примере ReportViewer), похоже, что уже существующие ContextMenu подключаются к Child-Element, а не к самому ReportViewer-Element. Но я не могу понять, какой элемент содержит ContextMenu - person WiiMaxx; 15.03.2013
comment
Еще раз спасибо за вашу информацию. Но чье дитя? WindowsFormsHost1.Child - это сам ReportViewer. И объект ReportViewer не имеет члена с именем Child - person tete; 15.03.2013
comment
@tele surly он не содержит такого свойства, но он все еще содержит элементы, например, в Controls (но есть только ..Spliter, который, насколько я могу сказать, ничего не делает), поэтому должен быть другой элемент, который содержит ваше ContextMenu вам следует выполнить поиск / создать метод (расширение recoment), который находит все дочерние элементы по типу, и при некотором взгляде вы получите то, что вам нужно, а затем вы можете всплыть, чтобы иметь возможность добавлять свои вещи - person WiiMaxx; 15.03.2013