WPF: Как разработать или отключить ContextMenu по умолчанию TextBox

Элемент, который вы пытались найти, не был в DOM , когда ваш скрипт работал.

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

Рассмотрим следующую разметку; сценарий # 1 не находит

, а сценарий # 2 преуспевает:


test div

Итак, что вы должны делать? У вас есть несколько вариантов:


Вариант 1: Переместите свой скрипт

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


  
  

Примечание: размещение скриптов внизу как правило, считается лучшей практикой .


Вариант 2: jQuery's ready()

Отмените свой сценарий до тех пор, пока DOM не будет полностью проанализирован, используя ready() :



Примечание. Вы можете просто привязать к DOMContentLoaded или window.onload, но у каждого есть свои оговорки. jQuery ready() предоставляет гибридное решение.


Вариант 3: Делегирование событий

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

blockquote>

Когда элемент вызывает событие (при условии, что это bubbling g6], и ничто не останавливает его распространение), каждый родитель в родословной этого элемента также получает событие. Это позволяет нам привязать обработчик к существующему элементу и примерным событиям, когда они пузырятся от его потомков ... даже те, которые добавлены после присоединения обработчика. Все, что нам нужно сделать, это проверить событие, чтобы узнать, был ли он поднят нужным элементом и, если да, запустите наш код.

jQuery on() выполняет эту логику для нас. Мы просто предоставляем имя события, селектор для желаемого потомка и обработчик событий:



Примечание: Обычно этот шаблон зарезервированы для элементов, которые не существовали во время загрузки или , чтобы избежать прикрепления большого количества обработчиков. Также стоит отметить, что, пока я прикреплял обработчик к document (для демонстрационных целей), вы должны выбрать ближайшего надежного предка.


Вариант 4: Атрибут defer

Используйте атрибут defer в

Для справки, вот код из этого внешнего скрипта :

document.getElementById("test").addEventListener("click", function(e){
   console.log("clicked: %o", this); 
});

Примечание: атрибут defer, безусловно, кажется , как волшебная пуля , но важно знать об оговорках ... 1. defer может использоваться только для внешних скриптов, т. е. для тех, у кого есть атрибут src. 2. знать о поддержке браузера , то есть: ошибка реализации в IE & lt; 10

29
задан Jon Lin 13 June 2012 в 15:39
поделиться

5 ответов

Из-за позднего отчета об ошибке мы обнаружили, что мы не можем использовать ApplicationComands Cut Paste and Copy непосредственно в частично доверенном приложении. Таким образом, использование этих команд в любой команде ваших элементов управления при выполнении абсолютно ничего не даст.

Итак, по сути, ответ Брэдса был почти готов, он выглядел правильно, т.е. без черного фона, но не решил проблему.

Мы решили «удалить» меню на основе ответа Брэдса, например:

<ContextMenu x:Key="TextBoxContextMenu" Width="0" Height="0" />

И использовать это пустое контекстное меню так:

<Style TargetType="{x:Type TextBox}">
  <Setter Property="ContextMenu" Value="{StaticResource TextBoxContextMenu}" />
</Style>
8
ответ дан 28 November 2019 в 01:20
поделиться

Чтобы стилизовать ContextMenu для всех TextBox, я бы сделал что-то вроде следующего:

Сначала, в разделе ресурсов, добавьте ContextMenu, которое вы планируете использовать в качестве стандартного ContextMenu, в текстовое поле.
например,

<ContextMenu x:Key="TextBoxContextMenu" Background="White">
  <MenuItem Command="ApplicationCommands.Copy" />
  <MenuItem Command="ApplicationCommands.Cut" />
  <MenuItem Command="ApplicationCommands.Paste" />
</ContextMenu>

Во-вторых, создайте стиль для ваших TextBox, который использует ресурс контекстного меню:

<Style TargetType="{x:Type TextBox}">
  <Setter Property="ContextMenu" Value="{StaticResource TextBoxContextMenu}" />
</Style>

Наконец, используйте текстовое поле как обычно:

<TextBox />

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

<TextBox ContextMenu="{StaticResource TextBoxContextMenu}" />

Надеюсь, это поможет!

32
ответ дан Brad Leach 28 November 2019 в 01:20
поделиться

Не имеет значения, если Вы не обеспечите ключ, он будет использовать TargetType в качестве ключа просто тот же путь мое использование в качестве примера:)

Взятый из MSDN на Стиле:

Установка TargetType свойство к эти TextBlock тип, не устанавливая x:Key неявно наборы x:Key к {x:Type TextBlock}. Это также означает, что>> при предоставлении вышеупомянутого Стиля x:Key значение чего-нибудь кроме {x:Type TextBlock} Стиль не был бы применен ко всем элементам TextBlock автоматически. Вместо этого необходимо применить стиль к эти TextBlock элементы явно.

http://msdn.microsoft.com/en-us/library/system.windows.style.targettype.aspx

2
ответ дан akjoshi 28 November 2019 в 01:20
поделиться

Попытайтесь удалить атрибут x:Key из ресурса Стиля, покинув TargetType. Я знаю, у Вас, как предполагается, есть это x:Key для ресурса, но если у Вас есть он наряду с Вашим TargetType, Ключ преобладает.

Вот демонстрационный стиль, который я использую в проекте очистить все подсказки в одном из моих приложений (это находится в Приложении. Ресурсы - уведомление, никакой Ключ)

 <Style
    TargetType="{x:Type ToolTip}">
    <Setter
      Property="Template">
      <Setter.Value>
        <ControlTemplate
          TargetType="{x:Type ToolTip}">
          <Grid
            Width="{TemplateBinding Width}"
            Height="{TemplateBinding Height}">
            <Rectangle
              RadiusX="9"
              RadiusY="9"
              Stroke="LightGray"
              StrokeThickness="2">
              <Rectangle.Fill>
                <RadialGradientBrush>
                  <GradientStop />
                  <GradientStop
                    Color="FloralWhite"
                    Offset="0" />
                  <GradientStop
                    Color="Cornsilk"
                    Offset="2" />
                </RadialGradientBrush>
              </Rectangle.Fill>
            </Rectangle>
            <ContentPresenter
              Margin="6 4 6 4" />
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
1
ответ дан 28 November 2019 в 01:20
поделиться

Странно. ContextMenu = "{x: Null}" не помогает.

Это действительно так:

<TextBox.ContextMenu>
    <ContextMenu Visibility="Collapsed">
    </ContextMenu>
</TextBox.ContextMenu>
17
ответ дан 28 November 2019 в 01:20
поделиться