拙网论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 140|回复: 1

关于SharpDevelop里的Condition

[复制链接]

949

主题

1001

帖子

3736

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3736
发表于 2018-6-7 10:14:40 | 显示全部楼层 |阅读模式
https://www.cnblogs.com/studyC/articles/SharpDevelopAddin.html


在所有的插件被加载到指定的扩展点后,插件树就被创建完毕了,
但是,我们知道,插件树创建后,每个插件在插件树的位置在就固定的,但是,如果某些情况下,我们希望一些插件不可使用或应该隐藏起来,

或者说有的插件在一些特定的情况下才是有意义的,
比如在Designtime下,只有我们选中了一个Component后,删除按钮才应该起作用,否则删除按钮应该是Disable的或不可见得,这种情况下我们

不可能去修改插件树,那应该如何做呢?
当然如果我们每次在选中或取消选中一个Component都去更新按钮的状态,理论上也是可以的,
这里我说“理论上”,是因为我没有成功过,让我们SD中的一个实际的Codon:
<Path name = "/SharpDevelop/Pads/ProjectBrowser/ToolBar/File">
<ToolbarItem id      = "OpenFile"
             icon    = "Icons.16x16.OpenFileIcon"
             tooltip = "${res:Gui.ProjectBrowser.Open}"
             class   = "ICSharpCode.SharpDevelop.Project.Commands.OpenFileFromProjectBrowser"/>
</Path>
上面的意图很简单,就是在ToolBar上放一个打开文件的一个ToolbarItem,SD启动后,你也看到这个ToolbarItem确实在呢,
但问题是:这个ToolbarItem的对象是访问不到的,至少我是没有办法访问到它,因为SD中这个一个ToolbarItem只是代表一个Command,
你点击它时,它就去创建它对应的Command,然后执行一下Run()函数,而且我花了几天时间查SD的代码,也没有发现能够取到这个对象的。
好吧,这是一个长话题,我就不多说了,不过即使能访问到,最好也不应该这样做,因为这样会使你的代码混乱。
让我们看看SD中如何解决这个问题的吧,其实很简单,SD中定义了一个叫做ConditionEvaluator的东西,
你可以根据自己的需求来控制插件的Enable或Visiable的状态,多个ConditionEvaluator进行与、或操作时还是有的麻烦的,
让我们从一个简单的例子开始吧。

假如我们有一开始就提到的需求:只有我们选中了一个Component后,删除按钮才应该起作用。
三步搞定:
第一步:
先写一个类,实现我们的控制逻辑
namespace AddIns
{
    public class DesignerHostOpenCondition : IConditionEvaluator
    {
        #region IConditionEvaluator Members

        public bool IsValid(object caller, Condition condition)
        {
            ICollection result = GetSelectedComponents();
            return result.Count >0;
            
        }
ICollection GetSelectedComponents()
{
//...
//your logic here...
}

        
    }
}
这个类必须实现IConditionEvaluator接口,我们的代码很简单,在选择的Component个数大于0时,返回True。
然后编译它到"HostAddin.dll"文件中。
第二步:
注册我们的DesignerHostOpenCondition ,
我们知道在每个插件中都有一个<Runtime>标签,像这样注册我们的DesignerHostOpenCondition:
<Runtime>
    <Import assembly = "HostAddin.dll">
      <ConditionEvaluator name="DesignerHostOpen" class="AddIns.DesignerHostOpenCondition"/>
    </Import>/>
</Runtime>
上面的XML很容易理解,这里我们给它指定一个唯一名字为“DesignerHostOpen”,这样别的地方可以引用它。
第三步:
使用"DesignerHostOpen",在你需要控制的MenuItem或ToolBarItem上,如下方式使用:
Codon如下:
<Path name = "/SharpDevelop/Workbench/ViewContent/ContextMenu/HostControl">
    <Condition name = "DesignerHostOpen" action="Exclude">
       <MenuItem id    = "Delete Selected"
                  label = "${res:Global.RemoveButtonText}"
                  icon = "Icons.16x16.DeleteIcon"
                  shortcut ="Delete"  
                  class = "AddIns.DeleteCommand" />
    </Condition>
</Path>
你会发现我们的MenuItem被一个<Condition> 包起来了,其实里面可以包多个项表示这个"DesignerHostOpen"对那几个Item有效。
要注意的是其中的:action="Exclude",action 可以有三个值,其余的两个是:Disable(控制当条件不满足时应该把MenuItem变成Disable)

、None(这个没有用,SD中似乎也没有用它的,而我们指定的"Exclude"会在条件不满足时让MenuItem变成不可见。
ok,运行程序,你就发现真的可以了。

工作机制很简单,SD会挂Appliction.Idle事件,大家知道在系统没有消息处理时就会出发这个事件,
而SD就是在这个事件里去尝试检查每个ConditionEvaluator的
回复

使用道具 举报

949

主题

1001

帖子

3736

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3736
 楼主| 发表于 2018-6-7 10:26:16 | 显示全部楼层
                        <ConditionEvaluator name="SolutionOpen" class="ICSharpCode.SharpDevelop.SolutionOpenConditionEvaluator"/>
                        <ConditionEvaluator name="IsProcessRunning" class="ICSharpCode.SharpDevelop.Debugging.IsProcessRunningConditionEvaluator"/>
                        <ConditionEvaluator name="OpenWindowState" class="ICSharpCode.SharpDevelop.OpenWindowStateConditionEvaluator"/>
                        <ConditionEvaluator name="WindowActive" class="ICSharpCode.SharpDevelop.WindowActiveConditionEvaluator"/>
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|抱朴守拙BBS

GMT+8, 2025-5-26 07:43 , Processed in 0.234603 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表