4

Suppose I am building an image editor using Rx.Net. The user can manipulate the canvas using the mouse. The manipulation that is applied depends on the currently selected tool. For example, there might be a "draw" tool and an "erase" tool. Only one tool can be selected at a time.

I have three streams; one for mouse events; one for commands issued by clicking the mouse; and another for tool selections:

IObservable<ITool> toolSelection;
IObservalbe<MouseState> mouse;
IObservable<ICommand> commands;

The commands stream depends on the other two: commands are issued when the user clicks the mouse and the command generated depends on the last selected tool. Note that a command should not be issued when the user changes tool, only when they click the mouse.

Now, I could store the last selected tool in a variable like this:

var selectedTool = defaultTool;
toolSelection.Subscribe(x => selectedTool = x);

I can use selectedTool to build the commands stream:

var commands = mouse.Select(x => selectedTool.CreateCommand(x));

However, this doesn't seem like the "reactive" way of doing things. Can I achieve this same logic using stream compositions?

I have looked at CombineLatest but it causes unwanted events to be generated when the user switches tool. I only want commands to be issued when the user clicks.

4

1 回答 1

4

听起来你需要.Switch().

试试这个代码:

IObservable<ICommand> commands =
    toolSelection
        .Select(t => mouse.Select(m => t.CreateCommand(m)))
        .Switch();

.Switch()在这种情况下,扩展方法采用 anIObservable<IObservable<ICommand>>并将其转换为 an ,方法IObservable<ICommand>是采用外部 observable 产生的最新 observable 并仅从中产生值并处理以前的 observable。

或者,用更英语的术语来说,每当用户点击一个新工具时,您都会在一个不错的查询中获得仅使用最新工具构建的鼠标命令流。

于 2016-07-07T00:00:00.487 回答