WPF绑定到ListBox的ContextMenu的MenuItem中的IsEnabled属性

时间:2013-08-16 09:27:05

标签: wpf isenabled

我正在查看有关数据绑定到contextmenus的其他主题,但我无法弄清楚如何让它工作,因为建议/答案对我不起作用。

我有一个列表框,它绑定到ObversableCollection - 工作正常。

现在我在该列表框中有一个上下文菜单。 contextmenu有4个项目可以激活,停用所选任务(这是列表框中表示的项目)。

由于权限,我需要控制,启用或禁用上下文菜单中的项目,因此我必须通过将它绑定到Listbox绑定到的相同Collection来设置ContextMenuItem的IsEnabled-Property。 / 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);
        }
    }
}

由于某种原因没有变化!

1 个答案:

答案 0 :(得分:0)

您可以尝试使用命令绑定(您需要prism):

...
<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替换startJobCanExecuteStart替换原始示例中的enablePermitted


编辑这可能有助于解释原始代码无效的原因。仅当属性的对象触发“PropertyChange”事件时,才会获取对绑定属性的更改。实施INotifyPropertyChanged可能也可以解决您的问题。


编辑原始代码的一个更微不足道的问题是它绑定到错误的对象 - 我假设FeedContextMenu上没有属性startPermitted(无论如何似乎没有定义)。


编辑上面还有一些问题: 1)绑定区分大小写,因此绑定应该是{Binding StartCommand}等。 2)您需要在列表中的各个项目上设置上下文菜单。以下方法可行:

    <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>