การพึ่งพาแบบวงกลมเมื่อเพิ่มการอ้างอิง (ผู้รับมอบสิทธิ์)

โดยพื้นฐานแล้วฉันมี 2 โปรเจ็กต์ แบบฟอร์มและการควบคุมผู้ใช้

ฉันต้องการให้ทั้งคู่อยู่ในโปรเจ็กต์ที่แตกต่างกัน แต่แบบฟอร์มจำเป็นต้องอ้างอิงถึงการควบคุมผู้ใช้เนื่องจากใช้การควบคุมผู้ใช้ และการควบคุมผู้ใช้จะต้องอ้างอิงถึงแบบฟอร์มเนื่องจากใช้คลาสแบบฟอร์มใดคลาสหนึ่ง เมื่อฉันเพิ่มอันที่สองเพราะต้องการ VS จะบ่นว่ามีการพึ่งพาแบบวงกลมซึ่งเข้าใจได้ ฉันจะแก้ปัญหานี้ได้อย่างไร?


person user3398315    schedule 22.04.2014    source แหล่งที่มา
comment
คุณสามารถแยกคลาสที่ไม่ใช่ UI ออกจากโปรเจ็กต์ Forms และสร้าง DLL ได้หรือไม่   -  person shree.pat18    schedule 22.04.2014
comment
สร้างโครงการที่สามที่มีทุกอย่างทั้งแบบฟอร์มและการควบคุมผู้ใช้ที่ต้องการ คุณจะไม่มีทางทำให้งานสร้างของคุณทำงานได้อย่างถูกต้องหากไม่ทำเช่นนั้น   -  person Peter Ritchie    schedule 22.04.2014


คำตอบ (4)


ตามหลักตรรกะแล้ว แบบฟอร์มควรขึ้นอยู่กับการควบคุมของผู้ใช้ คุณสามารถสร้างอินเทอร์เฟซเพื่อแทนที่แบบฟอร์มภายในโครงการควบคุมผู้ใช้ จากนั้นให้แบบฟอร์มใช้อินเทอร์เฟซนั้น

ตัวอย่างโครงการควบคุมผู้ใช้

public interface IForm
{
    string MyString { get; }
}

public class MyUserControl : UserControl
{
     public IForm Form { get; set; }

     private void ShowMyString()
     {
          String myString = Form.MyString;
          ...
     }
}

ตัวอย่างโครงการแบบฟอร์ม

public class MyForm : Form, IForm
{
    public MYString { get "My String Value"; }
}
person Adrian Toman    schedule 22.04.2014

ฉันคิดว่าต้นตอของปัญหาของคุณคือคุณไม่ได้แยกข้อกังวลของคุณระหว่างแบบฟอร์มและการควบคุมอย่างถูกต้อง

เนื่องจากคุณมีการควบคุม (ค่อนข้างทั่วไป) จึงไม่ควรขึ้นอยู่กับแบบฟอร์ม ตรรกะทั้งหมดของการควบคุมควรอยู่ภายในการควบคุมนั้นเอง แบบฟอร์มควรใช้เฉพาะกล่องดำเท่านั้นที่ใช้การควบคุม: เพิ่ม, ตั้งค่าฟิลด์สาธารณะ, เรียกวิธีการสาธารณะ ฯลฯ สิ่งอื่นใดที่ถือเป็นการละเมิดการห่อหุ้ม

บางครั้ง การควบคุมอาจจำเป็นต้องทราบสิ่งต่างๆ เกี่ยวกับรูปแบบหลัก ในกรณีนี้ ฉันขอแนะนำบางสิ่งง่ายๆ เช่น การเพิ่มฟิลด์ Parent ให้กับการควบคุมลูก

หากคุณต้องการบางสิ่งที่เฉพาะเจาะจงมากขึ้นจากแบบฟอร์ม คุณสามารถเพิ่มอินเทอร์เฟซได้ตลอดเวลา อินเทอร์เฟซควรแสดงรายการเฉพาะสิ่งที่ตัวควบคุมต้องการจากแบบฟอร์มเท่านั้น ตัวอย่างเช่น หากคุณต้องการขนาด คุณสามารถเพิ่ม:

public interface IControlParent {
  int Width { get; }
  int Height { get; }
}

ด้วยวิธีนี้ คุณจะเห็นการขึ้นต่อกันอย่างชัดเจน (สิ่งที่การควบคุมต้องการจากระดับบนสุด) และหากประเภทหลัก/สัญญามีการเปลี่ยนแปลง คุณไม่จำเป็นต้องดำเนินการมากนักเพื่อเปลี่ยนคลาสการควบคุมของคุณ

person ashes999    schedule 22.04.2014

คุณต้องแยกโค้ดของคุณออก ไม่ควรอ้างอิงถึงชุดประกอบแอปพลิเคชันเลย หากคุณพยายามนำรหัสนั้นกลับมาใช้ใหม่ในอนาคต exe ของแอปพลิเคชันควรควบคุมด้วย

ดังนั้น ให้นำคลาสจากโปรเจ็กต์แบบฟอร์มและย้ายคลาสไปยังโปรเจ็กต์ควบคุมหรือสร้างโปรเจ็กต์ไลบรารี ใส่คลาสลงไปแล้วอ้างอิงจากการควบคุมและโปรเจ็กต์แอปของคุณ

person Gusman    schedule 22.04.2014

คุณควรใช้เหตุการณ์ (ผู้รับมอบสิทธิ์) สมมติว่าภายในโปรเจ็กต์ฟอร์มของคุณคุณสร้างคลาสหนึ่ง: Form1 และภายในการควบคุมผู้ใช้คุณกำหนด UserControl1 UserControl1 จำเป็นต้องสร้างอินสแตนซ์และเรียกใช้เมธอดจาก Form1:

public class Form1
{
    public void Execute(string sMessage)
    {
        Console.WriteLine(sMessage);
        Console.ReadLine();
    }
}

การควบคุมผู้ใช้1:

public class UserControl
{
    public Func<object, object> oDel = null;

    public void Execute()
    {
        oDel?.Invoke("HELLO WORLD!");
    }
}

และจากคลาสที่สร้างอินสแตนซ์ UserControl มาเรียกมันว่า ParentClass:

public class ParentClass
{
    public void Execute()
    {
        UserControl oUserControl = new UserControl();
        oUserControl.oDel = Form1Action;
        oUserControl.Execute();
    }

    public object Form1Action(object obj)
    {
        string sObj = Convert.ToString(obj);

        Form1 oForm = new Form1();
        oForm.Execute(sObj);

        return null;
    }
}

แนวทางนี้ให้ความรับผิดชอบในการจัดการเหตุการณ์แก่ชั้นเรียนระดับสูง

person Andrés    schedule 04.04.2017