我正在实施一个简单的UserControl
,实际上是一个花哨的TextBox
。它的一个功能是您可以设置格式规范,并且此格式自动应用于其内容。例如,如果您将格式规范设置为"000"
且内容为"42"
,则会显示"042"
。
我正在按照MVP模式实现此UserControl
。实现类似于:how Implement usercontrol in winforms mvp pattern?。另外,请检查此问题:passive view and display logic
Title
中的View
属性如下所示:
private string title;
public string Title {
get { return title; }
set { title = value; titleTextBox.Text = presenter.Format(title); }
}
我觉得这种实现增加了不必要的耦合。例如,如果我更改了Presenter
的{{1}}方法,那么我将不得不浏览所有Format
并正确更改调用语句。
View
中的Title
属性如下所示:
View
public string Title {
get { return presenter.Title; }
set { presenter.Title = value; }
}
中的Title
属性如下所示:
Presenter
现在我必须在private string title;
public string Title {
get { return title; }
set { _view.SetTitle(this.Format(value); }
}
界面和SetTitle
实施中添加View
方法:
View
所以,通过这种方法,我得到了这种丑陋的public void SetTitle(string title) {
titleTextBox.Text = title;
}
类Java方法。
而不是调用SetTitle
在SetTitle
中创建新属性RealTitle
并设置它。这个View
前缀仍然很难看。
你能想到一个更好的方法吗?
Real
应该像这样使用:
UserControl
此代码段应在var c = new FancyTextBox();
c.Format = "000";
c.Text = "42";
Controls.Add(c);
内显示"042"
。
UserControl
A和B的行动是什么?我希望格式化的文本出现在UI中。格式代码位于Form FancyTextBoxView FancyTextBoxPresenter
| | |
| ftb.Text = "42" | |
|-------------------->| |
| | |
| | A |
| |----------------------------->|
| | |
| | B |
| |<-----------------------------|
。 Presenter
有一个View
,用于保存用户界面中的文字。
答案 0 :(得分:2)
为什么不直接定义View的Title属性?
public string Title {
get { return titleTextBox.Text; }
set { titleTextBox.Text = value; }
}
绝对没有理由定义额外的SetTitle方法。此外,在MVP中,您的视图永远不会知道您的演示者。
然后,只要触发了Format函数,就可以从那里设置视图的标题,例如:
void OnFormatCalled()
{
_view.Title = FormatTitle(_view.Title);
}
答案 1 :(得分:1)
我通常将View界面(和Model界面)注入Presenter。现在你有一个地方担心依赖和测试。
在设置标题并让Presenter订阅它时,让您的视图触发事件。然后,Presenter可以格式化文本并在视图上设置标题 - Presenter负责视图的表示,视图只是呈现内容。通过这种方式,视图真的很愚蠢,几乎没有逻辑。这有助于在单元测试期间被模拟,并使演示者非常容易测试。
还要注意格式化逻辑如何通过委托属性注入到Presenter中,从而将格式与演示者分离并使其可更改和可测试。无论如何只是一种方式...我喜欢这种方法。
public class Presenter
{
private IView _view;
private IModel _model;
public Func<string, string> TitleFormatter { get; set; }
public Presenter(IView view, IModel model)
{
_model = model;
_view = view;
_view.OnSetTitle += (s, e) => {
_view.Title = TitleFormatter(e.Text);
};
}
}
public View : IView
{
public event EventHandler<TitleChangedEventArgs> TitleChanged;
public SomeUserActionEvent(object sender, SomeUserInterfaceEventArgs e)
{
TitleChanged(e.Text);
}
}