นี่คือความถ่อมตัวของฉันใน MVP และประเด็นเฉพาะของคุณ
ครั้งแรกสิ่งที่ผู้ใช้สามารถโต้ตอบกับหรือเพียงแค่แสดงเป็นมุมมอง กฎหมายพฤติกรรมและลักษณะของมุมมองดังกล่าวจะอธิบายโดยอินเตอร์เฟซ อินเทอร์เฟซนั้นสามารถใช้งานได้โดยใช้ WinForms UI, คอนโซล UI, เว็บ UI หรือแม้กระทั่งไม่มี UI เลย (โดยปกติเมื่อทดสอบผู้นำเสนอ) - การใช้งานที่เป็นรูปธรรมไม่สำคัญตราบเท่าที่เป็นไปตามกฎหมายของอินเทอร์เฟซมุมมอง .
ประการที่สองมุมมองจะถูกควบคุมโดยผู้นำเสนอเสมอ กฎหมายพฤติกรรมและลักษณะของผู้นำเสนอดังกล่าวยังมีการอธิบายโดยอินเตอร์เฟซ อินเทอร์เฟซนั้นไม่มีความสนใจในการนำไปใช้งานมุมมองที่เป็นรูปธรรมตราบใดที่เป็นไปตามกฎหมายของอินเทอร์เฟซมุมมอง
ประการที่สามเนื่องจากผู้นำเสนอควบคุมมุมมองของตนเพื่อลดการอ้างอิงจึงไม่มีประโยชน์อะไรเลยที่จะมีมุมมองที่รับรู้อะไรเกี่ยวกับผู้นำเสนอ มีสัญญาที่ตกลงกันระหว่างผู้นำเสนอและมุมมองและระบุไว้โดยอินเทอร์เฟซมุมมอง
ผลกระทบของประการที่สามคือ:
- ผู้นำเสนอไม่มีวิธีการใด ๆ ที่มุมมองสามารถเรียกใช้ได้ แต่มุมมองมีเหตุการณ์ที่ผู้นำเสนอสามารถสมัครรับข้อมูลได้
- ผู้นำเสนอรู้มุมมองของตน ฉันชอบที่จะทำสิ่งนี้ให้สำเร็จด้วยการฉีดคอนสตรัคเตอร์บนพรีเซนเตอร์คอนกรีต
- มุมมองไม่มีความคิดว่าผู้นำเสนอควบคุมสิ่งใด จะไม่มีการจัดหาผู้นำเสนอใด ๆ
สำหรับปัญหาของคุณข้างต้นอาจมีลักษณะเช่นนี้ในโค้ดที่ค่อนข้างง่าย:
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();
}
}
นอกเหนือจากข้างต้นฉันมักจะมีIView
อินเทอร์เฟซพื้นฐานที่ฉันซ่อนShow()
และมุมมองของเจ้าของหรือชื่อมุมมองใด ๆ ที่มุมมองของฉันมักจะได้รับประโยชน์
สำหรับคำถามของคุณ:
1. เมื่อโหลด winform จะต้องได้รับ Treeview ฉันถูกต้องหรือไม่ที่คิดว่ามุมมองควรเรียกเมธอดเช่น Presenter.gettree () สิ่งนี้จะมอบสิทธิ์ให้กับโมเดลซึ่งจะได้รับข้อมูลสำหรับ Treeview สร้างและกำหนดค่าส่งกลับไปที่ ผู้นำเสนอซึ่งจะส่งผ่านไปยังมุมมองซึ่งจะกำหนดให้เป็นแผงพูด?
ฉันจะโทรIConfigurationView.SetTreeData(...)
จากIConfigurationPresenter.ShowView()
ก่อนที่จะโทรไปIConfigurationView.Show()
2. สิ่งนี้จะเหมือนกันสำหรับการควบคุมข้อมูลใด ๆ บน Winform เนื่องจากฉันมี datagridview ด้วยหรือไม่
ใช่ฉันจะเรียกIConfigurationView.SetTableData(...)
มันว่า มันขึ้นอยู่กับมุมมองที่จะจัดรูปแบบข้อมูลที่กำหนดให้ ผู้นำเสนอเพียงแค่ปฏิบัติตามสัญญาของมุมมองที่ต้องการข้อมูลแบบตาราง
3. แอพของฉันมีคลาสโมเดลจำนวนมากที่มีแอสเซมบลีเดียวกัน นอกจากนี้ยังรองรับสถาปัตยกรรมปลั๊กอินพร้อมปลั๊กอินที่ต้องโหลดเมื่อเริ่มต้น มุมมองจะเรียกเมธอดผู้นำเสนอหรือไม่ซึ่งจะเรียกวิธีที่โหลดปลั๊กอินและแสดงข้อมูลในมุมมองหรือไม่ ระดับใดที่จะควบคุมการอ้างอิงปลั๊กอิน มุมมองจะมีการอ้างอิงถึงพวกเขาหรือผู้นำเสนอหรือไม่?
หากปลั๊กอินเกี่ยวข้องกับมุมมองมุมมองควรรู้เกี่ยวกับสิ่งเหล่านี้ แต่ไม่ใช่ผู้นำเสนอ หากทุกอย่างเกี่ยวกับข้อมูลและโมเดลมุมมองก็ไม่ควรมีส่วนเกี่ยวข้องกับข้อมูล
4. ฉันคิดถูกต้องหรือไม่ว่ามุมมองควรจัดการทุกอย่างเกี่ยวกับการนำเสนอตั้งแต่สีโหนดทรีวิวไปจนถึงขนาดดาต้ากริด
ใช่. ลองนึกถึงว่าผู้นำเสนอเป็นผู้นำเสนอ XML ที่อธิบายข้อมูลและมุมมองที่รับข้อมูลและนำสไตล์ชีต CSS ไปใช้ ในแง่ที่เป็นรูปธรรมผู้นำเสนออาจเรียกIRoadMapView.SetRoadCondition(RoadCondition.Slippery)
และมุมมองนั้นทำให้ถนนเป็นสีแดง
แล้วข้อมูลสำหรับโหนดที่คลิกล่ะ?
5. ถ้าเมื่อฉันคลิกที่ treenodes ฉันควรส่งผ่านโหนดเฉพาะไปยังผู้นำเสนอจากนั้นผู้นำเสนอจะหาข้อมูลที่ต้องการจากนั้นถามโมเดลสำหรับข้อมูลนั้นก่อนที่จะนำเสนอกลับไปยังมุมมองหรือไม่
ถ้าเป็นไปได้ฉันจะส่งผ่านข้อมูลทั้งหมดที่จำเป็นเพื่อนำเสนอต้นไม้ในมุมมองในภาพเดียว แต่ถ้าข้อมูลบางส่วนมีขนาดใหญ่เกินไปที่จะส่งผ่านตั้งแต่เริ่มต้นหรือหากเป็นแบบไดนามิกและต้องการ "สแนปชอตล่าสุด" จากแบบจำลอง (ผ่านผู้นำเสนอ) ฉันจะเพิ่มสิ่งที่ต้องการevent LoadNodeDetailsEventHandler LoadNodeDetails
ในอินเทอร์เฟซมุมมองเพื่อให้ ผู้นำเสนอสามารถสมัครสมาชิกดึงรายละเอียดของโหนดในLoadNodeDetailsEventArgs.Node
(อาจจะผ่าน ID ของบางชนิด) จากโมเดลเพื่อให้มุมมองสามารถอัปเดตรายละเอียดโหนดที่แสดงเมื่อผู้รับมอบสิทธิ์ตัวจัดการเหตุการณ์กลับมา โปรดทราบว่าอาจจำเป็นต้องใช้รูปแบบ async หากการดึงข้อมูลอาจช้าเกินไปสำหรับประสบการณ์ของผู้ใช้ที่ดี