Caliburn Micro:从VM查询特定于视图的数据

时间:2011-06-02 08:35:05

标签: caliburn.micro

我是CM的新手,也是了解它我正在将应用程序从MVVM光迁移到Caliburn Micro。在我的原始代码中,我有一个VM响应一些UI操作(通过命令)将一些文本替换为字符串。视图使用文本框选择来给出位置。

因此VM具有(1)表示文本框文本的绑定字符串属性,(2)表示要添加的新文本的另一个绑定字符串属性,以及(3)需要知道选择开始和长度以便替换新文本的正确部分。

在我的原始代码中,我在VM命令实现中发送了一个自定义的DialogMessage派生对象,其中包含一些选择数据属性:发出命令时,消息已发送,视图收到并填充它用文本框选择开始和长度;然后VM回调并可以使用这些数据。

哪种在CM中实现这一点最好?我更喜欢VM保持对视图的不可知性,所以我不太喜欢从它访问视图的想法。我宁愿选择像上面那样基于“消息”的机制,但我不确定如何在CM中实现它:我可能会看看IResult,但我发现的大部分样本都与协同程序相关我不确定如何将VM的void ReplaceText()方法与后面的视图代码相关联。

有人能指出我正确的方向,和/或一些代码示例关于VM'命令'方法和视图之间的对话式交互吗?谢谢!

1 个答案:

答案 0 :(得分:0)

我可能会看看IResult选项。您将可以访问该视图,因此您在后面的代码中拥有的代码可以在您的结果中,而不是在您的VM中。

以下是ShowDialog结果的代码。我相信我从CM讨论组中抓住了它。有关更多示例,请在讨论group中搜索ShowDialog。 CM附带的GameLibrary示例也有一些。

  public class ShowDialog : IResult
    {
        private readonly Type _screenType;
        private readonly string _name;        

        [Import]
        public IWindowManager WindowManager { get; set; }

        public ShowDialog(string name)
        {
            _name = name;
        }

        public ShowDialog(Type screenType)
        {
            _screenType = screenType;
        }

        public void Execute(ActionExecutionContext context)
        {
            var screen = !string.IsNullOrEmpty(_name)
                             ? IoC.Get<object>(_name)
                             : IoC.GetInstance(_screenType, null);

            Dialog = screen;
            WindowManager.ShowDialog(screen);

            var deactivated = screen as IDeactivate;
            if (deactivated == null)
                Completed(this, new ResultCompletionEventArgs());
            else
            {
                deactivated.Deactivated += (o, e) =>
                                               {
                                                   if (e.WasClosed)
                                                   {
                                                       Completed(this, new ResultCompletionEventArgs());
                                                   }
                                               };
            }
        }

        public object Dialog { get; private set; }
        public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };

        public static ShowDialog Of<T>()
        {
            return new ShowDialog(typeof (T));
        }
    }

编辑:如果扩展TextBox,则可以绑定SelectedText。

 public class TextBoxEx : TextBox
    {
        public static readonly DependencyProperty SelectedTextProperty = DependencyProperty.Register("SelectedText", typeof(string), typeof(TextBoxEx), new PropertyMetadata("oa"));

        public TextBoxEx()
        {
            SelectionChanged += UpdateDependencyProperty;
        }

        private void UpdateDependencyProperty(object sender, RoutedEventArgs e)
        {
            SelectedText = base.SelectedText;
        }

        public new string SelectedText
        {
            get { return GetValue(SelectedTextProperty).ToString(); }
            set { SetValue(SelectedTextProperty, base.SelectedText); }
        }
    }

然后:

 <SLTest:TextBoxEx x:Name="MyTextBox2"
                 Grid.Row="1"
                 Width="200"
                 SelectedText="{Binding SelectedText, Mode=TwoWay}"
                 Text="This is some text." />