Creating a context menu in code

I will reorganize the three related but different DataGrids from xaml into code and hit the error by updating the context menu header text.

The command and text should be updated according to which cell in the data grid is the current cell. The header text is updated perfectly in xaml, but as you can see from the image below, it now appears as an empty line. The command itself works correctly and works with the correct grid cell.

Sets the property to change the title properties of the title text, but I suspect that my code does not replicate the binding as the xaml equivalent does. I'm also not sure if the Shared attribute is what I need for an account in code.

Does anyone see how I can improve the code I use?

Cheers,
Berryl

enter image description here

XAML style for setting bindings

<ContextMenu x:Key="NonProjectActivityContextMenu" x:Shared="true">

    <MenuItem 
        DataContext="{Binding MakeEachWeekDayFullDayCommand}" Command="{Binding .}" 
        Header="{Binding HeaderText}" InputGestureText="{Binding InputGestureText}"      
        />
    <MenuItem 
        DataContext="{Binding MakeFullDayCommand}" Command="{Binding .}" 
        Header="{Binding HeaderText}" InputGestureText="{Binding InputGestureText}"      
        />
</ContextMenu>

<!-- Bindings assumes a VmMenuItem (Command Reference) -->
<Style x:Key="ContextMenuItemStyle" TargetType="{x:Type MenuItem}">
    <Setter Property="Header" Value="{Binding HeaderText}"/>
    <Setter Property="InputGestureText" Value="{Binding InputGestureText}" />
    <Setter Property="Command" Value="{Binding Command}" />
    <Setter Property="Icon" Value="{Binding Icon}" />
    <Setter Property="Tag" Value="{Binding IdTag}" />
    <Setter Property="ItemsSource" Value="{Binding Children}"/>
</Style>

CODE

    protected virtual ContextMenu _GetContextMenu() {
        var menuItems = _dataContext.MenuItems.Select(menuItem => menuItem.ToMenuItem());
        var cm = new ContextMenu();
        foreach (var item in menuItems) {
            cm.Items.Add(item);
        }
        return cm;
    }

UPDATE

Well, the empty line was just my own stupidity - I did not initialize the header text! The snapshot below is what I'm getting now, which is an improvement. The text should be updated to say the day of the week, i.e. "Make Monday a full day," enter image description here

EDIT for Erno

I set the columns and style for the grid itself, as shown below, so I thought I could just extract the resource for the context menu and set it.

Nevertheless, I get an odd result, as you can see from the figure - it, as a context menu, covers the entire grid!

enter image description here

    private void OnDataGridLoaded(object sender, RoutedEventArgs e)
    {
        _dataContext = (ActivityCollectionViewModel)DataContext;

        IsSynchronizedWithCurrentItem = true;
        Style = (Style)FindResource(GRID_STYLE_NAME);

        _AddColumns();

        var timeSheetColumns = Columns.Cast<TimesheetGridColumn>();
        foreach (var col in timeSheetColumns)
        {
            col.SetHeader();
            col.SetCellStyle(this);
            col.SetBinding();
        }

        if(DesignerProperties.GetIsInDesignMode(this)) {
            // just so the designer doesn't hit a null reference on the data context
            ItemsSource = new ObservableCollection<ActivityViewModel>();
        }
        else {
            // ok, we have a runtime data context to work with
            ItemsSource = _dataContext.ActivityVms;
            InputBindings.AddRange(_GetKeyBindings());
            ContextMenu = _GetContextMenu();
            ContextMenu.Style = (Style)FindResource("ContextMenuItemStyle");
        }
    }


    private void OnDataGridLoaded(object sender, RoutedEventArgs e)
    {
        _dataContext = (ActivityCollectionViewModel)DataContext;

        IsSynchronizedWithCurrentItem = true;
        Style = (Style)FindResource(GRID_STYLE_NAME);

        _AddColumns();

        var timeSheetColumns = Columns.Cast<TimesheetGridColumn>();
        foreach (var col in timeSheetColumns)
        {
            col.SetHeader();
            col.SetCellStyle(this);
            col.SetBinding();
        }

        if(DesignerProperties.GetIsInDesignMode(this)) {
            // just so the designer doesn't hit a null reference on the data context
            ItemsSource = new ObservableCollection<ActivityViewModel>();
        }
        else {
            // ok, we have a runtime data context to work with
            ItemsSource = _dataContext.ActivityVms;
            InputBindings.AddRange(_GetKeyBindings());
            ContextMenu = _GetContextMenu();
            ContextMenu.Style = (Style)FindResource("ContextMenuItemStyle");
        }
    }

Last update

SO , . , , , , , . , , , . , , .

.

    private void OnCurrentCellChanged(object sender, EventArgs e)
    {
        if (ReferenceEquals(null, sender)) return;
        var grid = (DataGrid)sender;
        var selectedActivity = (ActivityViewModel)grid.CurrentItem;
        if (ReferenceEquals(selectedActivity, null)) return;

        if (_isEditableDayOfTheWeekColumn(grid.CurrentColumn))
        {
            var dowCol = (DayOfTheWeekColumn)grid.CurrentColumn;
            var index = Convert.ToInt32(dowCol.DowIndex);
            selectedActivity.SetSelectedAllocationVm(index);
        }
        else
        {
            selectedActivity.SetSelectedAllocationVm(-1);
        }
        var commands = selectedActivity
            .AllCommands
            .Select(vmMenuItem => vmMenuItem.Command.ToMenuItem());
        var cm = new ContextMenu();
        foreach (var item in commands)
        {
            //item.SetResourceReference(StyleProperty, "ContextMenuItemStyle");
            cm.Items.Add(item);
        }
        grid.ContextMenu = cm;
    }
+3
1

, . Style, ( ) Resources .

.

+1

All Articles