Powershell Forms - Как добавить обработчик события контекстного меню, чтобы предотвратить открытие, если элемент не выбран? - PullRequest
1 голос
/ 24 января 2020

У меня есть форма со списком, для которой у меня есть контекстное меню правой кнопкой мыши. Я бы хотел, чтобы меню появлялось только в том случае, если правый клик c находится над выбранным элементом в просмотре списка - в данный момент он появляется в любом месте просмотра списка windows и даже если ничего не выбрано.

Add-Type -AssemblyName System.Windows.Forms

$form = New-Object System.Windows.Forms.Form
$form.Text = "Foo"
$form.Size = '400,400'

$CMitemEnable = New-Object System.Windows.Forms.ToolStripMenuItem
$CMitemEnable.Text = 'Enable'
$CMitemDisable = New-Object System.Windows.Forms.ToolStripMenuItem
$CMitemDisable.Text = 'Disable'
$lvcontextmenu = New-Object System.Windows.Forms.ContextMenuStrip
$lvcontextmenu.ShowImageMargin = $false
$lvcontextmenu.Items.AddRange(@($CMitemEnable,$CMitemDisable))

$listviewbox = New-Object System.Windows.Forms.ListView
$listviewbox.View = [System.Windows.Forms.View]::Details
$listviewbox.Location = '15,20'
$listviewbox.Size = '340,150'
$listviewbox.Columns.Add('Host',180) | Out-Null
$listviewbox.FullRowSelect = $true
$listviewbox.MultiSelect = $false
# $listviewbox.ContextMenuStrip = $lvcontextmenu

$InfoText = New-Object System.Windows.Forms.TextBox
$InfoText.Location = '15,180'
$InfoText.Size = '340,120'
$InfoText.Multiline = $true
$InfoText.ScrollBars = "Vertical"
$InfoText.ReadOnly = $true

$form.Controls.AddRange(@($listviewbox,$InfoText))

$listviewbox.Items.AddRange(@('Foobar1','foobar2'))


$listviewbox.Add_MouseDown({
    $listviewbox.contextmenustrip = $null
    If($listviewbox.SelectedItems.Count){
        $listviewbox.contextmenustrip = $lvcontextmenu
        $InfoText.AppendText("`r`n" + ($this.SelectedItems[0].Text))
    }
    Else {
        $InfoText.AppendText("`r`nNothing selected")
        $listviewbox.contextmenustrip = $null
    }
})

# Show form
$form.ShowDialog() | Out-Null
$form.Dispose()

Я раньше не создавал контекстных меню и не могу понять, как реализовать обработчик событий для этого - есть примеры для C et c, но кто-то может указать мне правильное направление для Powershell, пожалуйста?

Ответы [ 3 ]

1 голос
/ 25 января 2020

Учитывая следующие моменты:

  • Не устанавливать ContextMenuStrip для события ListView
  • Обрабатывать MouseClick, поэтому сначала будет выбран элемент, затем Ваш код запускается. (В качестве альтернативы, если вы предпочитаете мышь вниз, вам необходимо поместить лог c в BeginInvoke, чтобы убедиться, что он будет работать после выбора элемента.)
  • Использование метода GetBound выбранного элемента и e.Location, проверьте, находится ли выбранное место внутри прямоугольника элемента
  • Показать ContextMenuStrip, используя Show, передав Cursor.Position

Вот рабочий пример:

Add-Type -AssemblyName System.Windows.Forms

$form = New-Object System.Windows.Forms.Form
$form.Text ="Test"
$form.Controls.AddRange(@(
    ($listView1 = [System.Windows.Forms.ListView] @{
        Dock = [System.Windows.Forms.DockStyle]::Fill;
        FullRowSelect = $true;
        View = [System.Windows.Forms.View]::Details;
    })
))
$contextMenuStrip1 = [System.Windows.Forms.ContextMenuStrip]@{}
$listView1.Columns.Add("C1") | Out-Null
$listView1.Columns.Add("C2") | Out-Null
$listView1.Items.Add("Item1") | Out-Null
$listView1.Items.Add("Item2") | Out-Null
$contextMenuStrip1.Items.Add("Menu 1") | Out-Null
$contextMenuStrip1.Items.Add("Menu 2") | Out-Null

$listView1.Add_MouseClick({param($sender,$e)
    if ($e.Button -eq [System.Windows.Forms.MouseButtons]::Right){
        if ($listView1.FocusedItem.GetBounds(
            [System.Windows.Forms.ItemBoundsPortion]::Entire).Contains($e.Location)){
            $contextMenuStrip1.Show([System.Windows.Forms.Cursor]::Position)
        }
    } 
})
$form.ShowDialog() | Out-Null
$form.Dispose()
$contextMenuStrip1.Dispose()
0 голосов
/ 24 января 2020

Следующий обработчик событий работает как задумано - комбинация советов от вас обоих, спасибо.

$listviewbox.Add_MouseUp({
    $listviewbox.contextmenustrip = $null
    If($listviewbox.SelectedItems.Count){
        $listviewbox.contextmenustrip = $lvcontextmenu
        $InfoText.AppendText("`r`n" + ($this.SelectedItems[0].Text))
    }
    Else {
        $InfoText.AppendText("`r`nNothing selected")
        $listviewbox.contextmenustrip = $null
    }
})
0 голосов
/ 24 января 2020

Может быть, есть более чистый способ, но у меня это работает:

Сначала удалите строку 22 ($listviewbox.ContextMenuStrip = $lvcontextmenu), а затем измените обработчик Click для $listviewbox на:

$listviewbox.Add_Click({
    If($this.SelectedItems.Count){
        $this.ContextMenuStrip = $lvcontextmenu
        $InfoText.AppendText("`r`n" + ($this.SelectedItems[0].Text))
    }
    Else {
        $this.ContextMenuStrip = $null
        $InfoText.AppendText("`r`nNothing selected")
    }
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...