WPF绑定到ListBox的ContextMenu的MenuItem中的IsEnabled属性 [英] WPF Binding to IsEnabled Property in ListBox' ContextMenu's MenuItem
问题描述
我正在查看与上下文菜单数据绑定有关的其他主题,但由于建议/答案对我不起作用,因此我无法弄清楚如何使其起作用.
我有一个列表框,该列表框绑定到一个ObversableCollection-运行正常.
现在我在该列表框中有一个上下文菜单.该contextmenu有4个项目可以激活,停用等选定的任务(这是列表框中显示的项目).
由于权限的原因,我需要控制上下文菜单中的项是启用还是禁用,因此我必须通过将ContextMenuItem的IsEnabled-Property绑定到与列表框绑定到的同一Collection来设置./p>
但是由于某些原因,上下文菜单项没有被禁用-该属性似乎被忽略了.
编辑:我现在已经实施了您的建议:
WPF
<ListView Margin="10,10,10,55" Name="listviewCurrentJobs" ItemsSource="{Binding JobCollection}">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Starten" Command="{Binding Path=startCommand}"/>
<MenuItem Header="Stoppen" Command="{Binding Path=stopCommand}"/>
<MenuItem Header="Aktivieren" Command="{Binding Path=enableCommand}"/>
<MenuItem Header="Deaktivieren" Command="{Binding Path=disableCommand}"/>
<MenuItem Header="Löschen" Command="{Binding Path=deleteCommand}"/>
</ContextMenu>
</ListView.ContextMenu>
<ListView.View>
<GridView>
<GridViewColumn Header="" Width="32">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding State}" Width="16"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Description}" />
</GridView>
</ListView.View>
</ListView>
C#
public class currentJob : MonitoringWindow
{
public string State { get; set; }
public string Description { get; set; }
public bool startPermitted { get; set; }
public bool stopPermitted { get; set; }
public bool enablePermitted { get; set; }
public bool disablePermitted { get; set; }
public bool deletePermitted { get; set; }
public ICommand StartCommand { get; private set; }
public ICommand StopCommand { get; private set; }
public ICommand EnableCommand { get; private set; }
public ICommand DisableCommand { get; private set; }
public ICommand DeleteCommand { get; private set; }
public currentJob()
{
StartCommand = new DelegateCommand(ExecuteStart, CanExecuteStart);
StopCommand = new DelegateCommand(ExecuteStop, CanExecuteStop);
EnableCommand = new DelegateCommand(ExecuteEnable, CanExecuteEnable);
DisableCommand = new DelegateCommand(ExecuteDisable, CanExecuteDisable);
DeleteCommand = new DelegateCommand(ExecuteDelete, CanExecuteDelete);
}
public bool CanExecuteStart()
{
return startPermitted;
}
public bool CanExecuteStop()
{
return stopPermitted;
}
public bool CanExecuteEnable()
{
return enablePermitted;
}
public bool CanExecuteDisable()
{
return disablePermitted;
}
public bool CanExecuteDelete()
{
return deletePermitted;
}
public void ExecuteStart()
{
currentJob curJob = ((currentJob)listviewCurrentJobs.SelectedItem);
string curJobName = curJob.Name;
if (new TaskService().GetFolder("DocuWare Notifications").Tasks[curJobName].Enabled == false)
new TaskService().GetFolder("DocuWare Notifications").Tasks[curJobName].Enabled = true;
new TaskService().GetFolder("DocuWare Notifications").Tasks[curJobName].Run();
loadJobs();
}
public void ExecuteStop()
{
if (new TaskService().GetFolder("DocuWare Notifications").Tasks[((currentJob)listviewCurrentJobs.SelectedItem).Name].Enabled == true)
{
new TaskService().GetFolder("DocuWare Notifications").Tasks[((currentJob)listviewCurrentJobs.SelectedItem).Name].Stop();
loadJobs();
}
}
public void ExecuteEnable()
{
new TaskService().GetFolder("DocuWare Notifications").Tasks[((currentJob)listviewCurrentJobs.SelectedItem).Name].Enabled = true;
loadJobs();
}
public void ExecuteDisable()
{
new TaskService().GetFolder("DocuWare Notifications").Tasks[((currentJob)listviewCurrentJobs.SelectedItem).Name].Enabled = false;
loadJobs();
}
public void ExecuteDelete()
{
new TaskService().GetFolder("DocuWare Notifications").DeleteTask(((currentJob)listviewCurrentJobs.SelectedItem).Name);
if (isMsSql)
{
mssqlconn.Open();
new SqlCommand("DELETE FROM dbo.DocuWareNotifications WHERE NAME = '" + ((currentJob)listviewCurrentJobs.SelectedItem).Name + "'", mssqlconn).ExecuteNonQuery();
mssqlconn.Close();
}
else
{
mysqlconn.Open();
new MySqlCommand("DELETE FROM DocuWareNotifications WHERE NAME = '" + ((currentJob)listviewCurrentJobs.SelectedItem).Name + "'", mysqlconn).ExecuteNonQuery();
mysqlconn.Close();
}
loadJobs();
}
}
public partial class MonitoringWindow : MetroWindow
{
[...]
foreach (Task task in new TaskService().GetFolder("DocuWare Notifications").Tasks)
{
if (task != null)
{
currentJob item = new currentJob();
switch (task.State)
{
case TaskState.Disabled:
item.State = "/DWNotDesigner;component/images/disabled.png";
item.Description = task.Name;
break;
case TaskState.Ready:
item.State = "/DWNotDesigner;component/images/active.png";
item.Description = task.Name;
break;
case TaskState.Running:
item.State = "/DWNotDesigner;component/images/working.png";
item.Description = task.Name;
break;
}
item.startPermitted = startPermitted;
item.stopPermitted = stopPermitted;
item.enablePermitted = enablePermitted;
item.disablePermitted = disablePermitted;
item.deletePermitted = deletePermitted;
_jobCollection.Add(item);
}
}
}
由于某些原因,没有变化!
您可以尝试使用命令绑定(您需要 ... 在这里,在原始示例中, 编辑这可能有助于解释为什么原始代码无法正常工作.仅当属性对象触发"PropertyChange"事件时,才会拾取对绑定属性的更改.实施 INotifyPropertyChanged 也可能会解决您的问题. 编辑与原始代码相比,一个更琐碎的问题是它绑定到了错误的对象-我认为FeedContextMenu上不存在startPermitted属性(无论如何似乎都没有定义). 编辑上面还有一些问题:
1)绑定区分大小写,因此绑定应为{Binding StartCommand}等.
2)您需要在列表中的各个项目上设置上下文菜单.以下将起作用: i was looking at the other threads regarding databinding to contextmenus but i couldnt figure out how to get it to work since the suggestions/answers wouldnt work for me. i have a listbox, which is bound to an ObversableCollection - that works fine. now i have a contextmenu inside that listbox. that contextmenu has 4 items to activate, deactivate etc the selected task (which is the item that is represented in the listbox). due to permissions, i need to control, wether the items in the contextmenu are enabled or disabled, so i have to set the IsEnabled-Property of the ContextMenuItem by binding it to the same Collection that the Listbox is bound to. but for some reason, the contextmenu items are not getting disabled - the property seems to be ignored. EDIT: i have now implemented your suggestion: WPF C# for some reason there is no change! You could try using command bindings (you'll need prism): ... Here, Edit It probably helps to explain why your original code does not work. Changes to bound properties are only picked up if a "PropertyChange" event is fired by the property's object. Implementing INotifyPropertyChanged would probably also fix your problem. Edit An even more trivial problem with your original code is that it is binding to the wrong object - I presume no property startPermitted exists on FeedContextMenu (which anyway doesn't seem to be defined). Edit There are still a few issues above:
1) the bindings are case-sensitive, so the binding should be {Binding StartCommand} etc.
2) You need to set the context menu on the individual items in the list. The following would work:
这篇关于WPF绑定到ListBox的ContextMenu的MenuItem中的IsEnabled属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!using Microsoft.Practices.Composite.Presentation.Commands;
public class currentJob
{
public ICommand StartCommand {get; private set;}
public currentJob ()
{
StartCommand = new DelegateCommand(ExecuteStart, CanExecuteStart);
}
private bool CanExecuteStart()
{
//Determine whether start can be executed
return true;
}
private void ExecuteStart()
{
//start here
}
}
ExecuteStart
替换了startJob
,而CanExecuteStart
替换了enablePermitted
.
<ListView Margin="10,10,10,55" Name="listviewCurrentJobs" ItemsSource="{Binding JobCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="2">
<StackPanel Orientation="Horizontal" MinHeight="20" Background="White">
<StackPanel.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Starten" Command="{Binding Path=StartCommand}"/>
<MenuItem Header="Stoppen" Command="{Binding Path=StopCommand}"/>
<MenuItem Header="Aktivieren" Command="{Binding Path=EnableCommand}"/>
<MenuItem Header="Deaktivieren" Command="{Binding Path=DisableCommand}"/>
<MenuItem Header="Löschen" Command="{Binding Path=DeleteCommand}"/>
</ContextMenu>
</StackPanel.ContextMenu>
<Image Source="{Binding State}" Width="16"/>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Margin="10,10,10,55" Name="listviewCurrentJobs" ItemsSource="{Binding JobCollection}">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Starten" Command="{Binding Path=startCommand}"/>
<MenuItem Header="Stoppen" Command="{Binding Path=stopCommand}"/>
<MenuItem Header="Aktivieren" Command="{Binding Path=enableCommand}"/>
<MenuItem Header="Deaktivieren" Command="{Binding Path=disableCommand}"/>
<MenuItem Header="Löschen" Command="{Binding Path=deleteCommand}"/>
</ContextMenu>
</ListView.ContextMenu>
<ListView.View>
<GridView>
<GridViewColumn Header="" Width="32">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding State}" Width="16"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Description}" />
</GridView>
</ListView.View>
</ListView>
public class currentJob : MonitoringWindow
{
public string State { get; set; }
public string Description { get; set; }
public bool startPermitted { get; set; }
public bool stopPermitted { get; set; }
public bool enablePermitted { get; set; }
public bool disablePermitted { get; set; }
public bool deletePermitted { get; set; }
public ICommand StartCommand { get; private set; }
public ICommand StopCommand { get; private set; }
public ICommand EnableCommand { get; private set; }
public ICommand DisableCommand { get; private set; }
public ICommand DeleteCommand { get; private set; }
public currentJob()
{
StartCommand = new DelegateCommand(ExecuteStart, CanExecuteStart);
StopCommand = new DelegateCommand(ExecuteStop, CanExecuteStop);
EnableCommand = new DelegateCommand(ExecuteEnable, CanExecuteEnable);
DisableCommand = new DelegateCommand(ExecuteDisable, CanExecuteDisable);
DeleteCommand = new DelegateCommand(ExecuteDelete, CanExecuteDelete);
}
public bool CanExecuteStart()
{
return startPermitted;
}
public bool CanExecuteStop()
{
return stopPermitted;
}
public bool CanExecuteEnable()
{
return enablePermitted;
}
public bool CanExecuteDisable()
{
return disablePermitted;
}
public bool CanExecuteDelete()
{
return deletePermitted;
}
public void ExecuteStart()
{
currentJob curJob = ((currentJob)listviewCurrentJobs.SelectedItem);
string curJobName = curJob.Name;
if (new TaskService().GetFolder("DocuWare Notifications").Tasks[curJobName].Enabled == false)
new TaskService().GetFolder("DocuWare Notifications").Tasks[curJobName].Enabled = true;
new TaskService().GetFolder("DocuWare Notifications").Tasks[curJobName].Run();
loadJobs();
}
public void ExecuteStop()
{
if (new TaskService().GetFolder("DocuWare Notifications").Tasks[((currentJob)listviewCurrentJobs.SelectedItem).Name].Enabled == true)
{
new TaskService().GetFolder("DocuWare Notifications").Tasks[((currentJob)listviewCurrentJobs.SelectedItem).Name].Stop();
loadJobs();
}
}
public void ExecuteEnable()
{
new TaskService().GetFolder("DocuWare Notifications").Tasks[((currentJob)listviewCurrentJobs.SelectedItem).Name].Enabled = true;
loadJobs();
}
public void ExecuteDisable()
{
new TaskService().GetFolder("DocuWare Notifications").Tasks[((currentJob)listviewCurrentJobs.SelectedItem).Name].Enabled = false;
loadJobs();
}
public void ExecuteDelete()
{
new TaskService().GetFolder("DocuWare Notifications").DeleteTask(((currentJob)listviewCurrentJobs.SelectedItem).Name);
if (isMsSql)
{
mssqlconn.Open();
new SqlCommand("DELETE FROM dbo.DocuWareNotifications WHERE NAME = '" + ((currentJob)listviewCurrentJobs.SelectedItem).Name + "'", mssqlconn).ExecuteNonQuery();
mssqlconn.Close();
}
else
{
mysqlconn.Open();
new MySqlCommand("DELETE FROM DocuWareNotifications WHERE NAME = '" + ((currentJob)listviewCurrentJobs.SelectedItem).Name + "'", mysqlconn).ExecuteNonQuery();
mysqlconn.Close();
}
loadJobs();
}
}
public partial class MonitoringWindow : MetroWindow
{
[...]
foreach (Task task in new TaskService().GetFolder("DocuWare Notifications").Tasks)
{
if (task != null)
{
currentJob item = new currentJob();
switch (task.State)
{
case TaskState.Disabled:
item.State = "/DWNotDesigner;component/images/disabled.png";
item.Description = task.Name;
break;
case TaskState.Ready:
item.State = "/DWNotDesigner;component/images/active.png";
item.Description = task.Name;
break;
case TaskState.Running:
item.State = "/DWNotDesigner;component/images/working.png";
item.Description = task.Name;
break;
}
item.startPermitted = startPermitted;
item.stopPermitted = stopPermitted;
item.enablePermitted = enablePermitted;
item.disablePermitted = disablePermitted;
item.deletePermitted = deletePermitted;
_jobCollection.Add(item);
}
}
}
...
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Command="{Binding StartCommand}"/>
...
</ContextMenu>
...
using Microsoft.Practices.Composite.Presentation.Commands;
public class currentJob
{
public ICommand StartCommand {get; private set;}
public currentJob ()
{
StartCommand = new DelegateCommand(ExecuteStart, CanExecuteStart);
}
private bool CanExecuteStart()
{
//Determine whether start can be executed
return true;
}
private void ExecuteStart()
{
//start here
}
}
ExecuteStart
replaces startJob
and CanExecuteStart
replaces enablePermitted
in the original example.
<ListView Margin="10,10,10,55" Name="listviewCurrentJobs" ItemsSource="{Binding JobCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="2">
<StackPanel Orientation="Horizontal" MinHeight="20" Background="White">
<StackPanel.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Starten" Command="{Binding Path=StartCommand}"/>
<MenuItem Header="Stoppen" Command="{Binding Path=StopCommand}"/>
<MenuItem Header="Aktivieren" Command="{Binding Path=EnableCommand}"/>
<MenuItem Header="Deaktivieren" Command="{Binding Path=DisableCommand}"/>
<MenuItem Header="Löschen" Command="{Binding Path=DeleteCommand}"/>
</ContextMenu>
</StackPanel.ContextMenu>
<Image Source="{Binding State}" Width="16"/>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>