从另一个 class 更新一个 pictureBox.Image
Updating a pictureBox.Image from another class
更新: 我很确定我找到了原因,我会在确定后立即用我的发现更新这个问题。这与将 2 个用户控件放在彼此上方有关,我在后面的一个上画图,这就是为什么我看不到更改的原因!我必须检查计时器的哈希码才能确定涉及 2 个计时器。
我正在开发一个 winforms 应用程序,我应用了 MVP 模式来分离职责和内容...(应用了被动视图方法,并且还触发事件以要求相应的演示者执行操作) .
我在这里也检查了其他问题和许多其他相关主题,但没有任何帮助...
问题描述:我在SplitContainer
的panel
中添加了一个UserControl
(SubView
)在 Form
(MainView
) 中。此 SubView
有自己的演示者 (SubPresenter
),要求它在用户从 [=22= 触发时切换其背景 (SwitchBackground()
、picturebox
) ].
问题: SwitchBackground()
方法在 MainView
(实际上是 MainPresenter
),但 SubView
上的更改未显示 。我还检查了(或至少尝试正确地做到这一点 :))该方法是否需要通过检查 InvokeRequired
.
将上下文切换到 GUI 线程或其他内容
我很乐意就此问题提出任何建议,因为我被困在那里,无法进一步编程...
这是我为说明问题而编写的示例应用程序(对于完整的示例项目,我将其上传到 github:link):
子视图:
public interface ISubView
{
void StartSwitchingBackground();
void StopSwitchingBackground();
}
public partial class SubView : UserControl, ISubView
{
private Bitmap plot;
private Brush brush1;
private Brush brush2;
private int drawCount;
private Timer timer;
public SubView()
{
InitializeComponent();
brush1 = new SolidBrush(Color.Yellow);
brush2 = new SolidBrush(Color.Blue);
timer = new Timer();
timer.Tick += OnTick;
}
private void OnTick(object sender, EventArgs e)
{
SwitchBackground();
}
private void SwitchBackground()
{
if (InvokeRequired)
Console.WriteLine("InvokeRequired"); // never happens, so i assume it is not considered a call from another thread...
if (plot == null || plot.Size != pictureBox.Size)
plot = new Bitmap((int)(pictureBox.Width*0.8), (int)(pictureBox.Height*0.8));
using (Graphics g = Graphics.FromImage(plot))
{
int x = plot.Width / 2;
int y = plot.Height / 2;
int w = plot.Width / 4;
int h = plot.Height / 4;
if (drawCount % 2 == 0)
{
g.Clear(Color.White);
g.FillRectangle(brush1, (x - w) / 2, (y - h) / 2, w, h);
}
else
{
g.Clear(Color.Black);
g.FillRectangle(brush2, (x - w) / 2, (y - h) / 2, w, h);
}
drawCount++;
}
pictureBox.Image = plot;
}
public void StartSwitchingBackground()
{
if (!timer.Enabled)
timer.Start();
Console.WriteLine("started");
}
public void StopSwitchingBackground()
{
if (timer.Enabled) timer.Stop();
Console.WriteLine("stopped");
}
private void btnStartSwitching_Click(object sender, EventArgs e)
{
StartSwitchingBackground();
}
private void btnStopSwitching_Click(object sender, EventArgs e)
{
StopSwitchingBackground();
}
}
副主持人:
public class SubPresenter
{
private ISubView view;
public SubPresenter(ISubView view)
{
this.view = view;
}
public void SwitchBackground()
{
view.StartSwitchingBackground();
}
public void StopSwitching()
{
view.StopSwitchingBackground();
}
}
主视图:
public interface IMainView
{
ISubView SubView { get; }
event EventHandler SwitchEventTriggered;
event EventHandler StopSwitchEventTriggered;
}
public partial class MainView : Form, IMainView
{
private SubView subView;
public MainView()
{
InitializeComponent();
subView = new SubView();
splitContainer1.Panel2.Controls.Add(subView);
subView.Dock = DockStyle.Fill;
subView.Anchor = AnchorStyles.Top & AnchorStyles.Left;
splitContainer1.Resize += splitContainer1_Resize;
}
void splitContainer1_Resize(object sender, EventArgs e)
{
subView.Size = splitContainer1.Panel2.Size;
}
private void btnStart_Click(object sender, EventArgs e)
{
StartSwitching();
}
private void StartSwitching()
{
OnStartSwitchingTriggered();
}
private void OnStartSwitchingTriggered()
{
var handler = SwitchEventTriggered;
if (handler == null) return;
handler(this, EventArgs.Empty);
}
private void btnStop_Click(object sender, EventArgs e)
{
StopSwitching();
}
private void StopSwitching()
{
OnStopSwitching();
}
private void OnStopSwitching()
{
var handler = StopSwitchEventTriggered;
if (handler == null) return;
handler(this, EventArgs.Empty);
}
public ISubView SubView { get { return this.subView; } }
public event EventHandler SwitchEventTriggered;
public event EventHandler StopSwitchEventTriggered;
}
主讲人:
public class MainPresenter
{
private readonly IMainView mainView;
private readonly SubPresenter subPresenter;
public MainPresenter(IMainView view)
{
this.mainView = view;
this.subPresenter = new SubPresenter(mainView.SubView);
mainView.SwitchEventTriggered += OnSwitchEventTriggerd;
mainView.StopSwitchEventTriggered += OnStopSwitchEventTriggered;
}
private void OnStopSwitchEventTriggered(object sender, EventArgs e)
{
subPresenter.StopSwitching();
}
private void OnSwitchEventTriggerd(object sender, EventArgs e)
{
subPresenter.SwitchBackground();
}
}
入口点:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainView mainView = new MainView();
MainPresenter mainPresenter = new MainPresenter(mainView);
Application.Run(mainView);
}
}
您在 MainView 中有两个 SubView 实例。
只使用subView1,可以删除所有出现的subView;
最低限度的修复是替换:
public ISubView SubView { get { return this.subView; } }
与:
public ISubView SubView { get { return this.subView1; } }
更新: 我很确定我找到了原因,我会在确定后立即用我的发现更新这个问题。这与将 2 个用户控件放在彼此上方有关,我在后面的一个上画图,这就是为什么我看不到更改的原因!我必须检查计时器的哈希码才能确定涉及 2 个计时器。
我正在开发一个 winforms 应用程序,我应用了 MVP 模式来分离职责和内容...(应用了被动视图方法,并且还触发事件以要求相应的演示者执行操作) .
我在这里也检查了其他问题和许多其他相关主题,但没有任何帮助...
问题描述:我在SplitContainer
的panel
中添加了一个UserControl
(SubView
)在 Form
(MainView
) 中。此 SubView
有自己的演示者 (SubPresenter
),要求它在用户从 [=22= 触发时切换其背景 (SwitchBackground()
、picturebox
) ].
问题: SwitchBackground()
方法在 MainView
(实际上是 MainPresenter
),但 SubView
上的更改未显示 。我还检查了(或至少尝试正确地做到这一点 :))该方法是否需要通过检查 InvokeRequired
.
我很乐意就此问题提出任何建议,因为我被困在那里,无法进一步编程...
这是我为说明问题而编写的示例应用程序(对于完整的示例项目,我将其上传到 github:link):
子视图:
public interface ISubView
{
void StartSwitchingBackground();
void StopSwitchingBackground();
}
public partial class SubView : UserControl, ISubView
{
private Bitmap plot;
private Brush brush1;
private Brush brush2;
private int drawCount;
private Timer timer;
public SubView()
{
InitializeComponent();
brush1 = new SolidBrush(Color.Yellow);
brush2 = new SolidBrush(Color.Blue);
timer = new Timer();
timer.Tick += OnTick;
}
private void OnTick(object sender, EventArgs e)
{
SwitchBackground();
}
private void SwitchBackground()
{
if (InvokeRequired)
Console.WriteLine("InvokeRequired"); // never happens, so i assume it is not considered a call from another thread...
if (plot == null || plot.Size != pictureBox.Size)
plot = new Bitmap((int)(pictureBox.Width*0.8), (int)(pictureBox.Height*0.8));
using (Graphics g = Graphics.FromImage(plot))
{
int x = plot.Width / 2;
int y = plot.Height / 2;
int w = plot.Width / 4;
int h = plot.Height / 4;
if (drawCount % 2 == 0)
{
g.Clear(Color.White);
g.FillRectangle(brush1, (x - w) / 2, (y - h) / 2, w, h);
}
else
{
g.Clear(Color.Black);
g.FillRectangle(brush2, (x - w) / 2, (y - h) / 2, w, h);
}
drawCount++;
}
pictureBox.Image = plot;
}
public void StartSwitchingBackground()
{
if (!timer.Enabled)
timer.Start();
Console.WriteLine("started");
}
public void StopSwitchingBackground()
{
if (timer.Enabled) timer.Stop();
Console.WriteLine("stopped");
}
private void btnStartSwitching_Click(object sender, EventArgs e)
{
StartSwitchingBackground();
}
private void btnStopSwitching_Click(object sender, EventArgs e)
{
StopSwitchingBackground();
}
}
副主持人:
public class SubPresenter
{
private ISubView view;
public SubPresenter(ISubView view)
{
this.view = view;
}
public void SwitchBackground()
{
view.StartSwitchingBackground();
}
public void StopSwitching()
{
view.StopSwitchingBackground();
}
}
主视图:
public interface IMainView
{
ISubView SubView { get; }
event EventHandler SwitchEventTriggered;
event EventHandler StopSwitchEventTriggered;
}
public partial class MainView : Form, IMainView
{
private SubView subView;
public MainView()
{
InitializeComponent();
subView = new SubView();
splitContainer1.Panel2.Controls.Add(subView);
subView.Dock = DockStyle.Fill;
subView.Anchor = AnchorStyles.Top & AnchorStyles.Left;
splitContainer1.Resize += splitContainer1_Resize;
}
void splitContainer1_Resize(object sender, EventArgs e)
{
subView.Size = splitContainer1.Panel2.Size;
}
private void btnStart_Click(object sender, EventArgs e)
{
StartSwitching();
}
private void StartSwitching()
{
OnStartSwitchingTriggered();
}
private void OnStartSwitchingTriggered()
{
var handler = SwitchEventTriggered;
if (handler == null) return;
handler(this, EventArgs.Empty);
}
private void btnStop_Click(object sender, EventArgs e)
{
StopSwitching();
}
private void StopSwitching()
{
OnStopSwitching();
}
private void OnStopSwitching()
{
var handler = StopSwitchEventTriggered;
if (handler == null) return;
handler(this, EventArgs.Empty);
}
public ISubView SubView { get { return this.subView; } }
public event EventHandler SwitchEventTriggered;
public event EventHandler StopSwitchEventTriggered;
}
主讲人:
public class MainPresenter { private readonly IMainView mainView;
private readonly SubPresenter subPresenter;
public MainPresenter(IMainView view)
{
this.mainView = view;
this.subPresenter = new SubPresenter(mainView.SubView);
mainView.SwitchEventTriggered += OnSwitchEventTriggerd;
mainView.StopSwitchEventTriggered += OnStopSwitchEventTriggered;
}
private void OnStopSwitchEventTriggered(object sender, EventArgs e)
{
subPresenter.StopSwitching();
}
private void OnSwitchEventTriggerd(object sender, EventArgs e)
{
subPresenter.SwitchBackground();
}
}
入口点:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainView mainView = new MainView();
MainPresenter mainPresenter = new MainPresenter(mainView);
Application.Run(mainView);
}
}
您在 MainView 中有两个 SubView 实例。 只使用subView1,可以删除所有出现的subView;
最低限度的修复是替换:
public ISubView SubView { get { return this.subView; } }
与:
public ISubView SubView { get { return this.subView1; } }