开发者

User-initiated action implementation

开发者 https://www.devze.com 2023-01-11 19:28 出处:网络
In Flash 10 there are methods that require that they are triggered from user-initiated actions like button click, keyboard up/down keys, etc.

In Flash 10 there are methods that require that they are triggered from user-initiated actions like button click, keyboard up/down keys, etc.

Is it possible to implement this behaviour in .NET? For example, if we have this subroutine:

void SomeMethod() {
   // Here some stuff
}

how to check inside it whether the method was called from a mouse click event handler?

Also we can think of this methods like the protected functions in World of Warcraft, if anyone knows what I mean.

EDIT: Looks like this behaviour is implemented in Silverlight — we can popup file dialogs (open, save) ONLY by mouse click or other user-initiated action, otherwise a SecurityException will be thrown. I want to achieve this bevaviour b开发者_StackOverflow中文版ut in my case it’s not a file dialog but our own methods.


Why not just provide it as a parameter?

void SomeMethod(bool userInitiated) {
   // Here some stuff
}

Given that you're already calling it, sometimes from an event handler and sometimes not, you already have that information.

EDIT: Another approach is to have a thread-static field which you set on entry to an event-handler and then reset on exit (in a finally block). Any code which wants to test whether they're "responding to a user action" can then test that field.

If that's not good enough, then I suspect the answer is simply "no".

EDIT: You can get at the call stack (see the StackTrace class) but that's relatively slow and can miss out stack frames due to inlining. There's also Code Access Security which may just about help you - but I doubt it.


It seems that you are writing some sort of plugin API. You want to provide a method that does something the user might not want, e.g. changes the clipboard contents, and you want to ensure that your plugins can call that method only in response to a user action.

The only way I can think of to do this is that the API needs to be continually aware of whether it is currently processing a user-initiated action or not. Presumably there will be some code in your program that calls the plugin-provided code, e.g.

if (plugin.HasHandlerForMouseClick)
    plugin.HandleMouseClick();

At this point you will need to remember that this is a user-initiated action. Once the method returns, that’s the end of the user-initiated action:

if (plugin.HasHandlerForMouseClick)
{
    _userInitiated = true;
    try
    {
        plugin.HandleMouseClick();
    }
    finally
    {
        _userInitiated = false;
    }
}

Then, in your “unsafe” method, e.g. the one to set the clipboard, you will have to check this flag:

public void SetClipboard(object newValue)
{
    if (!_userInitiated)
        return;    // or throw AccessDeniedException?

    // set clipboard here
}

As hinted by Jon, the field should be declared thread-static. This means that there is a separate copy of the field for each thread:

[ThreadStatic]
private static bool _userInitiated = false;
0

精彩评论

暂无评论...
验证码 换一张
取 消