Bu benim MVP ve sizin özel meselelerinizle ilgili alçakgönüllü yaklaşımım.
İlk olarak , bir kullanıcının etkileşime girebileceği veya sadece gösterilebileceği her şey bir görünümdür . Böyle bir görüşün kanunları, davranışları ve özellikleri bir arayüzle tanımlanır . Bu arayüz bir WinForms kullanıcı arayüzü, bir konsol kullanıcı arayüzü, bir web kullanıcı arayüzü kullanılarak veya hatta hiç kullanıcı arayüzü olmadan (genellikle bir sunum yapan kişiyi test ederken) uygulanabilir - somut uygulama, görünüm arayüzünün kanunlarına uyduğu sürece önemli değildir. .
İkinci olarak , bir görünüm her zaman bir sunum yapan kişi tarafından kontrol edilir . Böyle bir sunum yapan kişinin yasaları, davranışları ve özellikleri de bir arayüzle tanımlanır . Bu arayüz, kendi görüş arayüzünün yasalarına uyduğu sürece somut görünüm uygulamasına ilgi duymaz.
Üçüncüsü , sunum yapan kişi görünümünü kontrol ettiğinden, bağımlılıkları en aza indirmek için görünümün sunum yapan kişi hakkında herhangi bir şey bilmesinde gerçekten bir kazanç yoktur. Sunum yapan kişi ile görünüm arasında üzerinde anlaşmaya varılmış bir sözleşme vardır ve bu, görünüm arayüzünde belirtilir.
Etkileri Üçüncü şunlardır:
- Sunucunun, görünümün arayabileceği herhangi bir yöntemi yoktur, ancak görünümde sunum yapan kişinin abone olabileceği olaylar vardır.
- Sunum yapan kişi onun görüşünü bilir. Bunu somut sunucuya yapıcı enjeksiyonu ile gerçekleştirmeyi tercih ederim.
- Görünümün onu hangi sunum yapan kişinin kontrol ettiği hakkında hiçbir fikri yoktur; hiçbir zaman sunum yapan kişi sağlanmayacaktır.
Sorununuz için, yukarıdakiler biraz basitleştirilmiş kodda şöyle görünebilir:
interface IConfigurationView
{
event EventHandler SelectConfigurationFile;
void SetConfigurationFile(string fullPath);
void Show();
}
class ConfigurationView : IConfigurationView
{
Form form;
Button selectConfigurationFileButton;
Label fullPathLabel;
public event EventHandler SelectConfigurationFile;
public ConfigurationView()
{
this.selectConfigurationFileButton.Click += delegate
{
var Handler = this.SelectConfigurationFile;
if (Handler != null)
{
Handler(this, EventArgs.Empty);
}
};
}
public void SetConfigurationFile(string fullPath)
{
this.fullPathLabel.Text = fullPath;
}
public void Show()
{
this.form.ShowDialog();
}
}
interface IConfigurationPresenter
{
void ShowView();
}
class ConfigurationPresenter : IConfigurationPresenter
{
Configuration configuration = new Configuration();
IConfigurationView view;
public ConfigurationPresenter(IConfigurationView view)
{
this.view = view;
this.view.SelectConfigurationFile += delegate
{
var selectFilePresenter = Gimme.The<ISelectFilePresenter>();
selectFilePresenter.ShowView();
this.configuration.FullPath = selectFilePresenter.FullPath;
this.view.SetConfigurationFile(this.configuration.FullPath);
};
}
public void ShowView()
{
this.view.SetConfigurationFile(this.configuration.FullPath);
this.view.Show();
}
}
Yukarıdakilere ek olarak, genellikle benim görünümlerimin genellikle yararlandığı herhangi bir sahip görünümü veya başlığı IView
sakladığım bir temel arayüze sahibim Show()
.
Sorularınıza:
1. Winform yüklendiğinde, bir ağaç görünümü elde etmesi gerekir. Bu nedenle, görünümün şu gibi bir yöntemi çağırması gerektiğini düşünürken haklı mıyım: presenter.gettree (), bu da ağaç görünümü için verileri alacak, onu oluşturacak ve yapılandıracak, modele devredecektir. sunum yapan kişi, hangisi görünüme geçecek ve daha sonra onu basitçe, örneğin bir panele atayacak?
Ben çağırır IConfigurationView.SetTreeData(...)
dan IConfigurationPresenter.ShowView()
sağ çağrısı önce,IConfigurationView.Show()
2. Benim de bir veri görünümüne sahip olduğum için Winform üzerindeki herhangi bir veri kontrolü için bu aynı olur mu?
Evet, bunun IConfigurationView.SetTableData(...)
için arardım. Verilen verilerin biçimlendirilmesi görünüme bağlıdır. Sunum yapan kişi, görünümün tablo şeklindeki verileri istediği sözleşmesine uyar.
3. Uygulamam, aynı derlemeye sahip birkaç model sınıfına sahiptir. Ayrıca, başlangıçta yüklenmesi gereken eklentilere sahip bir eklenti mimarisini de destekler. Görünüm basitçe bir sunucu yöntemi çağırır mı, bu da eklentileri yükleyen ve bilgileri görünümde görüntüleyen bir yöntemi çağırır mı? Hangi katman daha sonra eklenti referanslarını kontrol eder. Görünüm onlara veya sunum yapan kişiye referanslar tutar mı?
Eklentiler görünümle ilgiliyse, görünümler onlar hakkında bilgi sahibi olmalı, ancak sunum yapan kişi olmamalıdır. Bunların hepsi veri ve modelle ilgiliyse, görünümün bunlarla hiçbir ilgisi olmamalıdır.
4. Görünümün, ağaç görünümü düğüm renginden datagrid boyutuna kadar sunumla ilgili her şeyi ele alması gerektiğini düşünürken haklı mıyım?
Evet. Bunu, verileri açıklayan XML sağlayan sunum yapan kişi ve verileri alan ve ona bir CSS stil sayfası uygulayan görünümü olarak düşünün. Somut olarak, sunum yapan kişi arayabilir IRoadMapView.SetRoadCondition(RoadCondition.Slippery)
ve ardından görünüm yolu kırmızı renkte gösterir.
Tıklanan düğümler için veriler ne olacak?
5. Ağaç düğümlerine tıkladığımda, belirli düğümden sunum yapan kişiye geçmeli ve bundan sonra sunum yapan kişi hangi verilere ihtiyaç duyduğunu hesaplayacak ve ardından bu veriyi görünüme geri sunmadan önce modeli soracaksa?
Mümkünse, ağacı bir görünümde sunmak için gereken tüm verileri tek seferde aktarırdım. Ancak bazı veriler baştan aktarılamayacak kadar büyükse veya doğası gereği dinamikse ve modelden (sunum yapan kişi aracılığıyla) "en son anlık görüntüye" ihtiyaç duyuyorsa event LoadNodeDetailsEventHandler LoadNodeDetails
, görünüm arayüzüne benzer bir şey eklerim , böylece sunum yapan kişi buna abone olabilir, düğümün ayrıntılarını LoadNodeDetailsEventArgs.Node
modelden alabilir (muhtemelen bir tür kimliği aracılığıyla), böylece görünüm, olay işleyici temsilcisi geri döndüğünde gösterilen düğüm ayrıntılarını güncelleyebilir. Verilerin alınması iyi bir kullanıcı deneyimi için çok yavaşsa, bunun eşzamansız kalıplarının gerekli olabileceğini unutmayın.