質問

Windows Phone 7.5 用の Silverlight アプリを作成しています。

設定したいので、LongListSelector 内の ContextMenu を参照したいのです。 .IsOpenfalse ContextMenu が表示されるとすぐに Click イベントが呼び出されます。これは自動的に行われるはずだと思っていましたが、そうではありません。

私の MenuItem の 1 つは、 <Grid> から collapsedvisible これはポップアップを模倣します。コードは正常に実行され、可視性は実際に変化します。ContextMenu が閉じない限り、アプリの UI にはグリッドが表示されません。

私のXAMLは、 LongListSelector が含まれています ContextMenu 呼ばれた Menu ContextMenuItem Click イベントで参照したいものです。

 <toolkit:LongListSelector x:Name="moviesLongList" Background="Transparent" IsFlatList="False" GroupHeaderTemplate="{StaticResource GroupHeaderTemplate}" GroupItemTemplate="{StaticResource GroupItemTemplate}" SelectionChanged="moviesLongList_SelectionChanged" GroupViewClosing="moviesLongList_GroupViewClosing" GroupViewOpened="moviesLongList_GroupViewOpened">

                    <toolkit:LongListSelector.GroupItemsPanel>
                        <ItemsPanelTemplate>
                            <toolkit:WrapPanel/>
                        </ItemsPanelTemplate>
                    </toolkit:LongListSelector.GroupItemsPanel>

                    <toolkit:LongListSelector.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Height="91" Margin="20,0,0,20" Orientation="Horizontal">
                                <toolkit:ContextMenuService.ContextMenu >
                                    <toolkit:ContextMenu x:Name="Menu" Opened="ContextMenu_Opened" Loaded="Menu_Loaded" Unloaded="Menu_Unloaded">
                                        <toolkit:ContextMenu.ItemTemplate>
                                            <DataTemplate>
                                                 <toolkit:MenuItem Header="{Binding}" Click="ContextMenuButton_Click" LostFocus="MenuItem_LostFocus" />
                                            </DataTemplate>
                                        </toolkit:ContextMenu.ItemTemplate>
                                    </toolkit:ContextMenu>
                                </toolkit:ContextMenuService.ContextMenu>

                                <Border HorizontalAlignment="Left" Width="61" Height="91" Background="{Binding ID, Converter={StaticResource ThumbImageConvert}}" />
                                <StackPanel Orientation="Vertical" HorizontalAlignment="Left" Width="395">
                                    <TextBlock x:Name="titleTextBox" Text="{Binding Title, Converter={StaticResource TitleConvert}}" Margin="6,0,6,0" d:LayoutOverrides="Width" FontSize="{StaticResource PhoneFontSizeLarge}" VerticalAlignment="Top" HorizontalAlignment="Left"/>
                                    <TextBlock x:Name="yearTextBox" Text="{Binding Year}" Margin="12,0,0,0" HorizontalAlignment="Left" FontSize="{StaticResource PhoneFontSizeMedium}" Foreground="{StaticResource PhoneSubtleBrush}" />
                                </StackPanel>
                            </StackPanel>
                        </DataTemplate>
                    </toolkit:LongListSelector.ItemTemplate>

                </toolkit:LongListSelector>

ContextMenuItem Click イベントの背後にある私のコード

  private void ContextMenuButton_Click(object sender, RoutedEventArgs e)
  {
        //
        // This is where I want to set Menu.IsOpen = false to close the ContextMenu.
        //

        if ((sender as MenuItem).Header.ToString() == "lend movie")
        {
                DisableAppBarIcons();
                LendPopUpOverlay.Visibility = System.Windows.Visibility.Visible;

        }

        if ((sender as MenuItem).Header.ToString() == "return to collection")
        {
            ... Do stuff
        }

        if ((sender as MenuItem).Header.ToString() == "add to boxset")
        {
             ... Do stuff

        }

        if ((sender as MenuItem).Header.ToString() == "delete")
        {
            ... Do stuff
        }

   }

ContextMenuのItemSourceを ContextMenu_Opened イベント。フィールドのタイプは両方とも List<String>.

private void ContextMenu_Opened(object sender, RoutedEventArgs e)
    {
        LentMovieObj = (sender as ContextMenu).DataContext as Movies;

        if (LentMovieObj.IsLent)
        {
            (sender as ContextMenu).ItemsSource = menuItemsReturn;
        }
        else
        {
            (sender as ContextMenu).ItemsSource = menuItemsLendOut;
        }
    }
役に立ちましたか?

解決

ContextMenu が閉じない理由はわかりませんが、解決策が 2 つあります。1 つ目は、MenuItem の親を取得することです。

private T GetParentOfType<T>(DependencyObject obj) where T : class
{
    if (obj == null) return null;

    var parent = VisualTreeHelper.GetParent(obj);
    while (parent != null)
    {
        if (parent is T) return parent as T;

        parent = VisualTreeHelper.GetParent(parent);
    }

    return null;
}

次に、クリックハンドラーからメニューを取得します

var menu = GetParentOfType<ContextMenu>(sender as MenuItem);
menu.IsOpen = false;

2 番目の解決策は、IsOpen をバッキング ビューモデルにバインドすることです。

<toolkit:ContextMenuService.ContextMenu >
    <toolkit:ContextMenu x:Name="Menu" Opened="ContextMenu_Opened" Loaded="Menu_Loaded" Unloaded="Menu_Unloaded" IsOpen="{Binding IsOpen}" ItemsSource="{Binding Items}">
        <toolkit:ContextMenu.ItemTemplate>
            <DataTemplate>
                <toolkit:MenuItem Header="{Binding}" Click="ContextMenuButton_Click" LostFocus="MenuItem_LostFocus" />
             </DataTemplate>
        </toolkit:ContextMenu.ItemTemplate>
     </toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>

オープンイベントを変更します。

private void ContextMenu_Opened(object sender, RoutedEventArgs e)
{
    LentMovieObj = (sender as ContextMenu).DataContext as Movies;

    if (LentMovieObj.IsLent)
    {
        (sender as ContextMenu).DataContext = new ContextMenuViewModel(menuItemsReturn);
    }
    else
    {
        (sender as ContextMenu).DataContext = ContextMenuViewModel(menuItemsLendOut);
    }
}

次にビューモデル

public class ContextMenuViewModel : INotifyPropertyChanged
{
    private bool _isOpen = true;

    public ContextMenuViewModel(IEnumerable<string> items)
    {
        Items = items;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public bool IsOpen
    {
        get { return _isOpen; }
        set { _isOpen = value; OnPropertyChanged("IsOpen"); }
    }

    public IEnumerable<String> Items { get; set; }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

次に、ViewModel の IsOpen プロパティを false に設定します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top