我正在将三个相关但不同的DataGrids从xaml重构为代码并遇到更新上下文菜单标题文本的问题。
命令和文本需要根据哪个数据网格单元是当前单元格进行更新。标题文本在xaml中更新正常,但正如您从下面的图片中看到的那样,它现在显示为空字符串。命令本身可以正常工作,并在正确的网格单元上工作。
标题文本的setter触发属性发生了变化,但我怀疑我的代码没有像xaml等效的那样复制绑定。我也不确定共享属性是否是我需要在代码中考虑的内容。
有谁看到我如何改进我正在使用的代码?
干杯,
Berryl
<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>
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;
}
空字符串部分只是我自己的愚蠢 - 我没有初始化标题文本!下面的图片是我现在得到的,这是一个改进。文本应该更新,以说明星期几,即“让星期一成为一整天”
我正在为网格本身设置列和样式,如下所示,所以我想我可以获取上下文菜单的资源并进行设置。
然而,正如你从图片中看到的那样,我得到一个奇怪的结果 - 就像上下文菜单覆盖整个网格一样!
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");
}
}
我尝试按this SO post制作我的绑定亲戚,但没有骰子。我的命令更新了,这意味着它在正确的单元格上执行,但我无法得到文本来反映它是哪个单元格。我终于决定立即构建上下文菜单,如下所示。它工作正常,虽然看起来我应该能够做得更好。
我会给Erno一个答案并将其关闭。
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;
}
答案 0 :(得分:1)
我的猜测是你想在代码中使用Style。 只需创建Style类的实例,设置其属性(包括绑定)并将其添加到树中的Resources属性。
接下来,使用生成的菜单项中的样式。