31 个解决方案
#1
最直接的,把控件的modifers属性设置为public,然后直接访问,不过建议还是通过委托或者接口去控制
#2
我设置过控件的modifers为public了 但是我在a窗口中没有办法访问b窗口中的控件,get set我都使用过了,但是还是不知道具体怎么弄,比如我在a窗口中button1的点击代码里想写b.button1.color=red;但是b后面点不出来button1;
#4
我在a界面选座的时候B界面是没有打开的
#5
通过委托,定义事件,可以实体跨窗体调用。
具体例子网上很多。
具体例子网上很多。
#6
与传值差不多, http://bbs.csdn.net/topics/390128592 第七种方法。
#7
通过委托,定义事件,可以实体跨窗体调用。
具体例子网上很多。
#8
其实最好的方法还是通过事件通知。就比如这样:
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
#9
8楼,正道。
#10
其实最好的方法还是通过事件通知。就比如这样:
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
#11
其实最好的方法还是通过事件通知。就比如这样:
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
#12
我在a界面里操作点击Button的时候B界面是没有打开的,而且B界面也不是通过a界面来打开的
if (message != null)
{
message(sender, e);
}
他这句的意思就是你B打开的时候才会通知,不打开message为Null就不会调用
#13
我在a界面里操作点击Button的时候B界面是没有打开的,而且B界面也不是通过a界面来打开的
其实最好的方法还是通过事件通知。就比如这样:
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
事件实际就是新建一个类,随便一个文件就可以了。
无论B界面是怎么打开的,只要B注册了事件,就可以接收消息
#14
楼主已经反复的声明了
我在a界面里操作点击Button的时候B界面是没有打开的,而且B界面也不是通过a界面来打开的
显然这不是简单的两个窗口间的控制问题,而是两个应用程序间的控制问题了
显然这不是简单的两个窗口间的控制问题,而是两个应用程序间的控制问题了
#15
楼主已经反复的声明了 我在a界面里操作点击Button的时候B界面是没有打开的,而且B界面也不是通过a界面来打开的
显然这不是简单的两个窗口间的控制问题,而是两个应用程序间的控制问题了
#16
数据库中设计一下吧或者用静态变量之类的
#17
16楼 正解
#18
楼主应该说清楚,A和B到底是同一个项目的两个窗体,还是两个不相干的项目
#19
楼主应该说清楚,A和B到底是同一个项目的两个窗体,还是两个不相干的项目
#20
不可以用数据库的吗?
A.B界面打开时读取数据库每个座位的状态:1.可用;2.已选取;3.已预订,根据座位的状态来显示按钮的颜色等,A界面点击按钮选取座位时,先读取数据库此座位的状态,判断是否可以进行选取操作,如若可选取,则更新数据库中此座位的状态为2.已选取状态.同理,B界面的操作流程类似,关键是获取判断更新座位的状态为3.已预定状态.
A.B界面打开时读取数据库每个座位的状态:1.可用;2.已选取;3.已预订,根据座位的状态来显示按钮的颜色等,A界面点击按钮选取座位时,先读取数据库此座位的状态,判断是否可以进行选取操作,如若可选取,则更新数据库中此座位的状态为2.已选取状态.同理,B界面的操作流程类似,关键是获取判断更新座位的状态为3.已预定状态.
#21
#22
同一项目两个窗体
那就把那个例子改改,A中实现委托并返回一个状态,B在画面启动时去调用委托,拿到那个返回值并根据返回值设置按钮颜色
#23
1、制作一个文件保存A、B窗体上的按钮的状态,不论哪个窗体显示,在其初始化时,都从这个文件中读取数据,进行初始化。一旦窗体上的按钮状态被改变后,就向这个文件中写入数据,保存它的状态,以备另一个窗体使用。
2、这个文件可以是任何格式的,就看你的喜好了。
2、这个文件可以是任何格式的,就看你的喜好了。
#24
明明用委托与事件就可以搞定的东西,代码也就那么几行,怎么弄这么复杂?
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
#25
明明用委托与事件就可以搞定的东西,代码也就那么几行,怎么弄这么复杂?
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
#26
我看了这么多回复越看越糊涂了,你能把怎么委托讲具体点吗
明明用委托与事件就可以搞定的东西,代码也就那么几行,怎么弄这么复杂?
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
我明天回来讲,贴代码
现在要出去了,不好意思
#27
我看了这么多回复越看越糊涂了,你能把怎么委托讲具体点吗
明明用委托与事件就可以搞定的东西,代码也就那么几行,怎么弄这么复杂?
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
我明天回来讲,贴代码
现在要出去了,不好意思
#28
首先,你设计的选座窗口和预约窗口,你说不是同时打开的,但也不排除同时打开。所有就有两种情况:同时打开和非同时打开。
但考虑到你的软件不是学习用的,而是实际项目,那么应该有个主窗体FormMain(通常有个主窗体这样的架构比较合理,处理起来相当灵活,一般子窗体把很多任务指令下达给主窗体,然后主窗体再去分配任务),FormA为选座窗口,FormB为预约窗口,A和B都是子窗体。在FormMain里应有如下声明:
FormA formA = new FormA();
FormB formB = new FormB();
Button1为座位1,Button2为座位2,........A和B一一对应。
一、A和B同时打开的情况:
先在FormA窗口定义委托与事件:
public delegate void CurrSeatSelected(int indexSeat); //委托
public event CurrSeatSelected seatSelected; //事件
在FormMain中注册事件(可在FormLoad()中注册):
formA.seatSelected += new FormA.CurrSeatSelected(TellFormBSeatSelected);
同时,FormMain中写函数TellFormBSeatSelected:
private void TellFormBSeatSelected(int indexSeat)
{
formB.ShowCurrSeatSelected(indexSeat); //传递座位号,表示已选,该座位已无法预约
}
在FormB中应有这个函数:
public void ShowCurrSeatSelected(int indexSeat)
{
this.Buttons[indexSeat].BackColor = Color.Red; //显示红色
}
那么,当在FormA选定某个座位后,比如2号座位,点击该座位后执行如下:
private void Buttons_Click(object sender, EventArgs e)
{
int seatIndex = ???.......; //获取座位号,这个看你是怎么设计的,反正就是获得座位的索引。即Buttons数组的索引
//下面就是把传递座位号已被选定的信息交给委托就行了
if (seatSelected != null)
seatSelected(seatIndex );
}
这样,当你在A中选定座位后,你可以看到在B中该座位也会显示红色,表示被选定,无法预约。
反之亦然,当有人预约某个座位后,同样在A中不可选,当然你可以设计时限,超过之后预约无效。
二、A和B不同时打开的情况:
相信这样的情况是绝大多数,而幸运的是,由于它们不是同时打开,所以编写的难度大大降低。但考虑到数据量大的情况,你就不好用文件形式存储数据,而应该选用数据库,可以选简单的数据库,比如Access。把A中的数据实时写进数据库,当打开B时刷新一次。然后就是同时打开的情况了。当然,AB同时打开后你也可以通过读写数据库的方式去编写,而不用委托,那样你就得新开一到两个线程专门去管理实时读写,你可根据情况而定。
但需要注意的是,如果用数据库方式,那么你就得避免同一个座位既被选定又被预约的情况出现,因为他们几乎是同时进行的,这就要求你要将相关的代码块锁定,即使用lock(){}结构,关于这个结构如果你不是很熟,你可以与查,网上很多的,也很详细。
我能提供的帮助就这些,希望有点用。如果有不当或错误之处,请见谅。
我也不是什么大神,就是一代码工而已。
祝愉快!
但考虑到你的软件不是学习用的,而是实际项目,那么应该有个主窗体FormMain(通常有个主窗体这样的架构比较合理,处理起来相当灵活,一般子窗体把很多任务指令下达给主窗体,然后主窗体再去分配任务),FormA为选座窗口,FormB为预约窗口,A和B都是子窗体。在FormMain里应有如下声明:
FormA formA = new FormA();
FormB formB = new FormB();
Button1为座位1,Button2为座位2,........A和B一一对应。
一、A和B同时打开的情况:
先在FormA窗口定义委托与事件:
public delegate void CurrSeatSelected(int indexSeat); //委托
public event CurrSeatSelected seatSelected; //事件
在FormMain中注册事件(可在FormLoad()中注册):
formA.seatSelected += new FormA.CurrSeatSelected(TellFormBSeatSelected);
同时,FormMain中写函数TellFormBSeatSelected:
private void TellFormBSeatSelected(int indexSeat)
{
formB.ShowCurrSeatSelected(indexSeat); //传递座位号,表示已选,该座位已无法预约
}
在FormB中应有这个函数:
public void ShowCurrSeatSelected(int indexSeat)
{
this.Buttons[indexSeat].BackColor = Color.Red; //显示红色
}
那么,当在FormA选定某个座位后,比如2号座位,点击该座位后执行如下:
private void Buttons_Click(object sender, EventArgs e)
{
int seatIndex = ???.......; //获取座位号,这个看你是怎么设计的,反正就是获得座位的索引。即Buttons数组的索引
//下面就是把传递座位号已被选定的信息交给委托就行了
if (seatSelected != null)
seatSelected(seatIndex );
}
这样,当你在A中选定座位后,你可以看到在B中该座位也会显示红色,表示被选定,无法预约。
反之亦然,当有人预约某个座位后,同样在A中不可选,当然你可以设计时限,超过之后预约无效。
二、A和B不同时打开的情况:
相信这样的情况是绝大多数,而幸运的是,由于它们不是同时打开,所以编写的难度大大降低。但考虑到数据量大的情况,你就不好用文件形式存储数据,而应该选用数据库,可以选简单的数据库,比如Access。把A中的数据实时写进数据库,当打开B时刷新一次。然后就是同时打开的情况了。当然,AB同时打开后你也可以通过读写数据库的方式去编写,而不用委托,那样你就得新开一到两个线程专门去管理实时读写,你可根据情况而定。
但需要注意的是,如果用数据库方式,那么你就得避免同一个座位既被选定又被预约的情况出现,因为他们几乎是同时进行的,这就要求你要将相关的代码块锁定,即使用lock(){}结构,关于这个结构如果你不是很熟,你可以与查,网上很多的,也很详细。
我能提供的帮助就这些,希望有点用。如果有不当或错误之处,请见谅。
我也不是什么大神,就是一代码工而已。
祝愉快!
#29
再补充点:关于第二种不同时打开的情况:
假如有50个座位,那你的button数组也就是50的长度,初始值均为0,表示都没被选中,1表示选中,2表示预定。
在FormA中,一旦点击选定某个座位号,比如10号
{
//将10号座位号的状态写入文件或数据库,也就是说10号座位状态为1,即已被选中
}
那么好了,你可以把A关掉了,然后你打开了B,那你就要在B加载的时候去读文件,刚好10号被选中了,你就可以显示红色。
{
//判断10号座位状态为1,就应该显示红色
//当然,在B加载时你不可能只判断10号,而是所有座位都判断,既然只选过10号,那么其他座位就不能显示红色,表示其他座位都可以预约。
}
原理就这么简单。
那么,真正的问题是,既然是选座系统,那么有可能很多个人在同时操作,有人在选座,有人在预约,那就涉及到实时刷新的问题了,就需要多线程出场了。有可能有种情况,有人心里面想选11号,但恰恰就在他点击鼠标前的一刹那,另外的人就已经将11号定了,而在预约人的界面中还没及时刷新,其实应对这种情况也很简单,你可以用if去判断,提示他座位已被选,请预约其他座位。
我说这些的意思是,你应该要考虑很多因素进去,因为软件这东西,一环套一环,往往几个不同的功能在代码编写的层面上是交叉的,不能独立对待。
假如有50个座位,那你的button数组也就是50的长度,初始值均为0,表示都没被选中,1表示选中,2表示预定。
在FormA中,一旦点击选定某个座位号,比如10号
{
//将10号座位号的状态写入文件或数据库,也就是说10号座位状态为1,即已被选中
}
那么好了,你可以把A关掉了,然后你打开了B,那你就要在B加载的时候去读文件,刚好10号被选中了,你就可以显示红色。
{
//判断10号座位状态为1,就应该显示红色
//当然,在B加载时你不可能只判断10号,而是所有座位都判断,既然只选过10号,那么其他座位就不能显示红色,表示其他座位都可以预约。
}
原理就这么简单。
那么,真正的问题是,既然是选座系统,那么有可能很多个人在同时操作,有人在选座,有人在预约,那就涉及到实时刷新的问题了,就需要多线程出场了。有可能有种情况,有人心里面想选11号,但恰恰就在他点击鼠标前的一刹那,另外的人就已经将11号定了,而在预约人的界面中还没及时刷新,其实应对这种情况也很简单,你可以用if去判断,提示他座位已被选,请预约其他座位。
我说这些的意思是,你应该要考虑很多因素进去,因为软件这东西,一环套一环,往往几个不同的功能在代码编写的层面上是交叉的,不能独立对待。
#30
个人理解
A窗口中显示所有座位可选和不可选用不同颜色区分,B窗口也是同样的功能,这样的话一个窗口就可以搞定,使用静态变量记录已选的座位号,在打开窗口时读取下就可以了。
如果楼主真的需要两个窗口实现方法一样。在打开B窗口时读取下就可以了。
A窗口中显示所有座位可选和不可选用不同颜色区分,B窗口也是同样的功能,这样的话一个窗口就可以搞定,使用静态变量记录已选的座位号,在打开窗口时读取下就可以了。
如果楼主真的需要两个窗口实现方法一样。在打开B窗口时读取下就可以了。
#31
委托,用事件触发,不然就算你暂时解决了winform控件间交互问题,以后还是会遇到很多类似的麻烦。我尝试过直接窗体交互,最后还是采用的委托的办法,委托的机制更适合解决这类问题。你还可以参考WPF的绑定思想
#1
最直接的,把控件的modifers属性设置为public,然后直接访问,不过建议还是通过委托或者接口去控制
#2
最直接的,把控件的modifers属性设置为public,然后直接访问,不过建议还是通过委托或者接口去控制
#3
与传值差不多,
http://bbs.csdn.net/topics/390128592 第七种方法。
#4
我设置过控件的modifers为public了 但是我在a窗口中没有办法访问b窗口中的控件,get set我都使用过了,但是还是不知道具体怎么弄,比如我在a窗口中button1的点击代码里想写b.button1.color=red;但是b后面点不出来button1;
最直接的,把控件的modifers属性设置为public,然后直接访问,不过建议还是通过委托或者接口去控制
#5
通过委托,定义事件,可以实体跨窗体调用。
具体例子网上很多。
具体例子网上很多。
#6
与传值差不多, http://bbs.csdn.net/topics/390128592 第七种方法。
#7
通过委托,定义事件,可以实体跨窗体调用。
具体例子网上很多。
#8
其实最好的方法还是通过事件通知。就比如这样:
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
#9
8楼,正道。
#10
其实最好的方法还是通过事件通知。就比如这样:
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
#11
其实最好的方法还是通过事件通知。就比如这样:
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
#12
我在a界面里操作点击Button的时候B界面是没有打开的,而且B界面也不是通过a界面来打开的
if (message != null)
{
message(sender, e);
}
他这句的意思就是你B打开的时候才会通知,不打开message为Null就不会调用
#13
我在a界面里操作点击Button的时候B界面是没有打开的,而且B界面也不是通过a界面来打开的
其实最好的方法还是通过事件通知。就比如这样:
1 定义事件
public class EventTest
{
public delegate void SendMessage(object sender, EventArgsTest e);
public static event SendMessage message;
public static void SendMessageFunction(object sender,EventArgsTest e)
{
if (message != null)
{
message(sender, e);
}
}
}
public class EventArgsTest:EventArgs
{
public string Message{get;set;}
}
2 在b中注册事件
public B()
{
InitializeComponent();
EventTest.message += EventTest_message;
}
3 在a 的按钮事件中添加事件通知
EventArgsTest test=new EventArgsTest();
test.Message="test message";
EventTest.SendMessageFunction(sender, test);
事件实际就是新建一个类,随便一个文件就可以了。
无论B界面是怎么打开的,只要B注册了事件,就可以接收消息
#14
楼主已经反复的声明了
我在a界面里操作点击Button的时候B界面是没有打开的,而且B界面也不是通过a界面来打开的
显然这不是简单的两个窗口间的控制问题,而是两个应用程序间的控制问题了
显然这不是简单的两个窗口间的控制问题,而是两个应用程序间的控制问题了
#15
楼主已经反复的声明了 我在a界面里操作点击Button的时候B界面是没有打开的,而且B界面也不是通过a界面来打开的
显然这不是简单的两个窗口间的控制问题,而是两个应用程序间的控制问题了
#16
数据库中设计一下吧或者用静态变量之类的
#17
16楼 正解
#18
楼主应该说清楚,A和B到底是同一个项目的两个窗体,还是两个不相干的项目
#19
楼主应该说清楚,A和B到底是同一个项目的两个窗体,还是两个不相干的项目
#20
不可以用数据库的吗?
A.B界面打开时读取数据库每个座位的状态:1.可用;2.已选取;3.已预订,根据座位的状态来显示按钮的颜色等,A界面点击按钮选取座位时,先读取数据库此座位的状态,判断是否可以进行选取操作,如若可选取,则更新数据库中此座位的状态为2.已选取状态.同理,B界面的操作流程类似,关键是获取判断更新座位的状态为3.已预定状态.
A.B界面打开时读取数据库每个座位的状态:1.可用;2.已选取;3.已预订,根据座位的状态来显示按钮的颜色等,A界面点击按钮选取座位时,先读取数据库此座位的状态,判断是否可以进行选取操作,如若可选取,则更新数据库中此座位的状态为2.已选取状态.同理,B界面的操作流程类似,关键是获取判断更新座位的状态为3.已预定状态.
#21
#22
同一项目两个窗体
那就把那个例子改改,A中实现委托并返回一个状态,B在画面启动时去调用委托,拿到那个返回值并根据返回值设置按钮颜色
#23
1、制作一个文件保存A、B窗体上的按钮的状态,不论哪个窗体显示,在其初始化时,都从这个文件中读取数据,进行初始化。一旦窗体上的按钮状态被改变后,就向这个文件中写入数据,保存它的状态,以备另一个窗体使用。
2、这个文件可以是任何格式的,就看你的喜好了。
2、这个文件可以是任何格式的,就看你的喜好了。
#24
明明用委托与事件就可以搞定的东西,代码也就那么几行,怎么弄这么复杂?
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
#25
明明用委托与事件就可以搞定的东西,代码也就那么几行,怎么弄这么复杂?
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
#26
我看了这么多回复越看越糊涂了,你能把怎么委托讲具体点吗
明明用委托与事件就可以搞定的东西,代码也就那么几行,怎么弄这么复杂?
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
我明天回来讲,贴代码
现在要出去了,不好意思
#27
我看了这么多回复越看越糊涂了,你能把怎么委托讲具体点吗
明明用委托与事件就可以搞定的东西,代码也就那么几行,怎么弄这么复杂?
至于你怎么选座,那就是线程执行的时序问题,这与一个控件控制另外窗体控件是两码事吧。
LZ,千万别被搞糊涂了。
我明天回来讲,贴代码
现在要出去了,不好意思
#28
首先,你设计的选座窗口和预约窗口,你说不是同时打开的,但也不排除同时打开。所有就有两种情况:同时打开和非同时打开。
但考虑到你的软件不是学习用的,而是实际项目,那么应该有个主窗体FormMain(通常有个主窗体这样的架构比较合理,处理起来相当灵活,一般子窗体把很多任务指令下达给主窗体,然后主窗体再去分配任务),FormA为选座窗口,FormB为预约窗口,A和B都是子窗体。在FormMain里应有如下声明:
FormA formA = new FormA();
FormB formB = new FormB();
Button1为座位1,Button2为座位2,........A和B一一对应。
一、A和B同时打开的情况:
先在FormA窗口定义委托与事件:
public delegate void CurrSeatSelected(int indexSeat); //委托
public event CurrSeatSelected seatSelected; //事件
在FormMain中注册事件(可在FormLoad()中注册):
formA.seatSelected += new FormA.CurrSeatSelected(TellFormBSeatSelected);
同时,FormMain中写函数TellFormBSeatSelected:
private void TellFormBSeatSelected(int indexSeat)
{
formB.ShowCurrSeatSelected(indexSeat); //传递座位号,表示已选,该座位已无法预约
}
在FormB中应有这个函数:
public void ShowCurrSeatSelected(int indexSeat)
{
this.Buttons[indexSeat].BackColor = Color.Red; //显示红色
}
那么,当在FormA选定某个座位后,比如2号座位,点击该座位后执行如下:
private void Buttons_Click(object sender, EventArgs e)
{
int seatIndex = ???.......; //获取座位号,这个看你是怎么设计的,反正就是获得座位的索引。即Buttons数组的索引
//下面就是把传递座位号已被选定的信息交给委托就行了
if (seatSelected != null)
seatSelected(seatIndex );
}
这样,当你在A中选定座位后,你可以看到在B中该座位也会显示红色,表示被选定,无法预约。
反之亦然,当有人预约某个座位后,同样在A中不可选,当然你可以设计时限,超过之后预约无效。
二、A和B不同时打开的情况:
相信这样的情况是绝大多数,而幸运的是,由于它们不是同时打开,所以编写的难度大大降低。但考虑到数据量大的情况,你就不好用文件形式存储数据,而应该选用数据库,可以选简单的数据库,比如Access。把A中的数据实时写进数据库,当打开B时刷新一次。然后就是同时打开的情况了。当然,AB同时打开后你也可以通过读写数据库的方式去编写,而不用委托,那样你就得新开一到两个线程专门去管理实时读写,你可根据情况而定。
但需要注意的是,如果用数据库方式,那么你就得避免同一个座位既被选定又被预约的情况出现,因为他们几乎是同时进行的,这就要求你要将相关的代码块锁定,即使用lock(){}结构,关于这个结构如果你不是很熟,你可以与查,网上很多的,也很详细。
我能提供的帮助就这些,希望有点用。如果有不当或错误之处,请见谅。
我也不是什么大神,就是一代码工而已。
祝愉快!
但考虑到你的软件不是学习用的,而是实际项目,那么应该有个主窗体FormMain(通常有个主窗体这样的架构比较合理,处理起来相当灵活,一般子窗体把很多任务指令下达给主窗体,然后主窗体再去分配任务),FormA为选座窗口,FormB为预约窗口,A和B都是子窗体。在FormMain里应有如下声明:
FormA formA = new FormA();
FormB formB = new FormB();
Button1为座位1,Button2为座位2,........A和B一一对应。
一、A和B同时打开的情况:
先在FormA窗口定义委托与事件:
public delegate void CurrSeatSelected(int indexSeat); //委托
public event CurrSeatSelected seatSelected; //事件
在FormMain中注册事件(可在FormLoad()中注册):
formA.seatSelected += new FormA.CurrSeatSelected(TellFormBSeatSelected);
同时,FormMain中写函数TellFormBSeatSelected:
private void TellFormBSeatSelected(int indexSeat)
{
formB.ShowCurrSeatSelected(indexSeat); //传递座位号,表示已选,该座位已无法预约
}
在FormB中应有这个函数:
public void ShowCurrSeatSelected(int indexSeat)
{
this.Buttons[indexSeat].BackColor = Color.Red; //显示红色
}
那么,当在FormA选定某个座位后,比如2号座位,点击该座位后执行如下:
private void Buttons_Click(object sender, EventArgs e)
{
int seatIndex = ???.......; //获取座位号,这个看你是怎么设计的,反正就是获得座位的索引。即Buttons数组的索引
//下面就是把传递座位号已被选定的信息交给委托就行了
if (seatSelected != null)
seatSelected(seatIndex );
}
这样,当你在A中选定座位后,你可以看到在B中该座位也会显示红色,表示被选定,无法预约。
反之亦然,当有人预约某个座位后,同样在A中不可选,当然你可以设计时限,超过之后预约无效。
二、A和B不同时打开的情况:
相信这样的情况是绝大多数,而幸运的是,由于它们不是同时打开,所以编写的难度大大降低。但考虑到数据量大的情况,你就不好用文件形式存储数据,而应该选用数据库,可以选简单的数据库,比如Access。把A中的数据实时写进数据库,当打开B时刷新一次。然后就是同时打开的情况了。当然,AB同时打开后你也可以通过读写数据库的方式去编写,而不用委托,那样你就得新开一到两个线程专门去管理实时读写,你可根据情况而定。
但需要注意的是,如果用数据库方式,那么你就得避免同一个座位既被选定又被预约的情况出现,因为他们几乎是同时进行的,这就要求你要将相关的代码块锁定,即使用lock(){}结构,关于这个结构如果你不是很熟,你可以与查,网上很多的,也很详细。
我能提供的帮助就这些,希望有点用。如果有不当或错误之处,请见谅。
我也不是什么大神,就是一代码工而已。
祝愉快!
#29
再补充点:关于第二种不同时打开的情况:
假如有50个座位,那你的button数组也就是50的长度,初始值均为0,表示都没被选中,1表示选中,2表示预定。
在FormA中,一旦点击选定某个座位号,比如10号
{
//将10号座位号的状态写入文件或数据库,也就是说10号座位状态为1,即已被选中
}
那么好了,你可以把A关掉了,然后你打开了B,那你就要在B加载的时候去读文件,刚好10号被选中了,你就可以显示红色。
{
//判断10号座位状态为1,就应该显示红色
//当然,在B加载时你不可能只判断10号,而是所有座位都判断,既然只选过10号,那么其他座位就不能显示红色,表示其他座位都可以预约。
}
原理就这么简单。
那么,真正的问题是,既然是选座系统,那么有可能很多个人在同时操作,有人在选座,有人在预约,那就涉及到实时刷新的问题了,就需要多线程出场了。有可能有种情况,有人心里面想选11号,但恰恰就在他点击鼠标前的一刹那,另外的人就已经将11号定了,而在预约人的界面中还没及时刷新,其实应对这种情况也很简单,你可以用if去判断,提示他座位已被选,请预约其他座位。
我说这些的意思是,你应该要考虑很多因素进去,因为软件这东西,一环套一环,往往几个不同的功能在代码编写的层面上是交叉的,不能独立对待。
假如有50个座位,那你的button数组也就是50的长度,初始值均为0,表示都没被选中,1表示选中,2表示预定。
在FormA中,一旦点击选定某个座位号,比如10号
{
//将10号座位号的状态写入文件或数据库,也就是说10号座位状态为1,即已被选中
}
那么好了,你可以把A关掉了,然后你打开了B,那你就要在B加载的时候去读文件,刚好10号被选中了,你就可以显示红色。
{
//判断10号座位状态为1,就应该显示红色
//当然,在B加载时你不可能只判断10号,而是所有座位都判断,既然只选过10号,那么其他座位就不能显示红色,表示其他座位都可以预约。
}
原理就这么简单。
那么,真正的问题是,既然是选座系统,那么有可能很多个人在同时操作,有人在选座,有人在预约,那就涉及到实时刷新的问题了,就需要多线程出场了。有可能有种情况,有人心里面想选11号,但恰恰就在他点击鼠标前的一刹那,另外的人就已经将11号定了,而在预约人的界面中还没及时刷新,其实应对这种情况也很简单,你可以用if去判断,提示他座位已被选,请预约其他座位。
我说这些的意思是,你应该要考虑很多因素进去,因为软件这东西,一环套一环,往往几个不同的功能在代码编写的层面上是交叉的,不能独立对待。
#30
个人理解
A窗口中显示所有座位可选和不可选用不同颜色区分,B窗口也是同样的功能,这样的话一个窗口就可以搞定,使用静态变量记录已选的座位号,在打开窗口时读取下就可以了。
如果楼主真的需要两个窗口实现方法一样。在打开B窗口时读取下就可以了。
A窗口中显示所有座位可选和不可选用不同颜色区分,B窗口也是同样的功能,这样的话一个窗口就可以搞定,使用静态变量记录已选的座位号,在打开窗口时读取下就可以了。
如果楼主真的需要两个窗口实现方法一样。在打开B窗口时读取下就可以了。
#31
委托,用事件触发,不然就算你暂时解决了winform控件间交互问题,以后还是会遇到很多类似的麻烦。我尝试过直接窗体交互,最后还是采用的委托的办法,委托的机制更适合解决这类问题。你还可以参考WPF的绑定思想