从另一个类更新pictureBox.Image

时间:2015-01-10 21:43:29

标签: c# image winforms picturebox mvp

更新:我很确定我找到了原因,我会在得到肯定后立即用我的调查结果更新这个问题。它与将2个用户控件放在彼此之上并且我在后面的那个上面绘制有关,为什么我看不到这些变化!我必须检查计时器的哈希码,以确定涉及2个计时器。


我正在开发一个winforms应用程序,并且我已经应用了MVP模式来分离职责和内容......(应用被动视图方法,以及触发事件以要求相应的演示者执行操作)。 / p>

我还在这里检查了其他问题以及许多其他相关主题,但没有任何帮助...

问题描述:我将UserControlSubView)添加到SplitContainer的{​​{1}}中,panel位于{{1}内(Form)。此MainView有自己的演示者(SubView),只要用户从{{1}触发该背景,就需要它切换背景(SubPresenterSwitchBackground()) }。

问题:picturebox方法从MainView(实际上来自SwitchBackground())触发时,MainView方法被执行(我已调试)在MainPresenter上显示强项>未显示更改。我还检查过(或者至少尝试过这样做:))如果方法需要通过检查SubView将上下文切换到GUI线程中。

我很高兴有关于这个问题的任何建议,因为我被困在那里,无法进一步编程......

这是我编写的一个示例应用程序来说明问题(对于完整的示例项目,我将其上传到github:link):

子视图:

InvokeRequired

SubPresenter:

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();
    }
}

的MainView:

public class SubPresenter
{
    private ISubView view;

    public SubPresenter(ISubView view)
    {
        this.view = view;
    }

    public void SwitchBackground()
    {
        view.StartSwitchingBackground();
    }

    public void StopSwitching()
    {
        view.StopSwitchingBackground();
    }
}

MainPresenter:

公共类MainPresenter     {         私人只读IMainView mainView;

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;
}

切入点:

    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();
    }
}

1 个答案:

答案 0 :(得分:0)

您在MainView中有两个SubView实例。 仅使用subView1,可以删除所有出现的subView;

最低要求是替换:

public ISubView SubView { get { return this.subView; } }

使用:

public ISubView SubView { get { return this.subView1; } }