Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows窗体应用程序,如何在自定义控件之间通信?_C#_.net_Winforms_User Controls - Fatal编程技术网

C# Windows窗体应用程序,如何在自定义控件之间通信?

C# Windows窗体应用程序,如何在自定义控件之间通信?,c#,.net,winforms,user-controls,C#,.net,Winforms,User Controls,我有三个用户控件。以下是对它们的描述: 1) 第一个用户控件(ucCountry)包含显示xml文件中国家名称的组合框 2) 第二个用户控件(ucChannelType)包含两个单选按钮,一个用于选择电视,另一个用于选择广播频道类型 3) 第三个用户控件(ucChannels)将填充ucCountry提供国家名称和ucChannelType提供类型的所有频道 现在,如何在表单中的这些用户控件之间进行通信。我需要将usercontrols与表单解耦。所以,我需要使用事件。但是如果ucCountry

我有三个用户控件。以下是对它们的描述: 1) 第一个用户控件(ucCountry)包含显示xml文件中国家名称的组合框

2) 第二个用户控件(ucChannelType)包含两个单选按钮,一个用于选择电视,另一个用于选择广播频道类型

3) 第三个用户控件(ucChannels)将填充ucCountry提供国家名称和ucChannelType提供类型的所有频道

现在,如何在表单中的这些用户控件之间进行通信。我需要将usercontrols与表单解耦。所以,我需要使用事件。但是如果ucCountry触发了一个事件(比如CountryChanged事件)并且ucChannels订阅了该事件,那么如何从ucChannelType获取通道类型


提前感谢…

最好的解决方案是向自定义控件添加属性。后台可能没有字段,getter将只从内部标准控制的属性中获取数据。

您可以在
ucCountry
上拥有一个属性,该属性提供当前选定的国家。比如:

public Country SelectedCountry
{
    get
    {
        return (Country) myComboBox.SelectedItem;
    }
}
然后,当事件激发时,其他控件将获取属性

另一个选项是使用自定义事件委托,因此
ucCountry.CountryChanged
的事件处理程序将有一个country参数:

public delegate void CountryChangedDelegate(Country sender)

public event CountryChangedDelegate CountryChanged;
UC通道中的事件处理程序:

public void ucCountry_CountryChanged(Country sender)
{
    //do something with the new country
}
myUcCountry.CountryChanged += new CountryChangedDelegate(ucCountry_CountryChanged);
并将事件连接到以下频道:

public void ucCountry_CountryChanged(Country sender)
{
    //do something with the new country
}
myUcCountry.CountryChanged += new CountryChangedDelegate(ucCountry_CountryChanged);

您需要为提供数据的控件提供公共属性,以及为使用数据的控件注册事件的公共方法。下面是一个简单的例子:

public static void Test()
{
    var a = new A();
    var b = new B();
    var c = new C() {a = a, b = b};
    a.OnChange += c.Changed;
    b.OnChange += c.Changed;
    a.State = "CA";
    b.ChannelType = "TV";
}

class A
{
    private string _state;

    public string State
    {
        get { return _state; }
        set
        {
            _state = value;
            if (OnChange != null) OnChange(this, EventArgs.Empty);
        }
    }

    public event EventHandler<EventArgs> OnChange;
}

class B
{
    private string _channelType;

    public string ChannelType
    {
        get { return _channelType; }
        set
        {
            _channelType = value;
            if (OnChange != null) OnChange(this, EventArgs.Empty);
        }
    }

    public event EventHandler<EventArgs> OnChange;
}

class C
{
    public A a { get; set; }
    public B b { get; set; }
    public void Changed(object sender, EventArgs e)
    {
        Console.WriteLine("State: {0}\tChannelType: {1}", a.State, b.ChannelType);
    }
}
公共静态无效测试()
{
var a=新的a();
var b=新的b();
var c=newc(){a=a,b=b};
a、 OnChange+=c.已更改;
b、 OnChange+=c.已更改;
a、 State=“CA”;
b、 ChannelType=“电视”;
}
甲级
{
私有字符串状态;
公共字符串状态
{
获取{return\u state;}
设置
{
_状态=值;
if(OnChange!=null)OnChange(this,EventArgs.Empty);
}
}
公共事件事件处理程序OnChange;
}
B类
{
私有字符串_channelType;
公共字符串信道类型
{
获取{return\u channelType;}
设置
{
_channelType=值;
if(OnChange!=null)OnChange(this,EventArgs.Empty);
}
}
公共事件事件处理程序OnChange;
}
C类
{
公共A{get;set;}
公共B{get;set;}
公共无效已更改(对象发送方、事件参数e)
{
WriteLine(“状态:{0}\tChannel类型:{1}”,a.State,b.ChannelType);
}
}

我没有退出,明白吗,假设
控制A
有一个按钮,
控制B
怎么会知道按钮在被点击
控制A
的同一时刻被点击了呢?@ThunderWiring这是愚蠢的答案(我承认我写了它)它并没有真正回答这个问题,adharris的答案是正确的。与adharris的答案相比,这是一个更详细的答案:@Thunderwilling,它并不更详细。它只包含事件部分,不包含属性。