【问题标题】:WPF Close Window Closes Source Window. Why?WPF 关闭窗口 关闭源窗口。为什么?
【发布时间】:2011-09-26 11:28:18
【问题描述】:

我遇到的问题有点难以描述,所以请听一听。

我只是从另一个窗口打开一个窗口,然后尝试关闭第二个窗口。如果我使用第二个 InputBindings 的命令,第二个就可以正常关闭。如果我直接调用 close 它会关闭第一个和第二个窗口。我希望代码会在这种情况下有所帮助。

WPF:Window1View(关键部分)

<Grid>
  <Button Content="Button" Command="{Binding RptKeyDownCommand}" />
</Grid>

Window1ViewModel:(列表的缩写)

using GalaSoft.MvvmLight.Command;
var _runCommand = new RelayCommand(() => Run(), () => CanRun());

    public void Run()
    {
        var v = new Window2();
        var vm = new Window2ViewModel();
        vm.RequestClose += v.Close;
        v.DataContext = vm;
        v.ShowDialog();
    }

    public event Action RequestClose;

    var _closeCommand = new RelayCommand(() => Close(), () => CanClose());
    public void Close()
    {
        if (RequestClose != null)
            RequestClose();
    }

WPF:Window2View

<Window.InputBindings>
    <KeyBinding Key="Escape" Command="{Binding CloseCommand}" />
</Window.InputBindings>
    <TextBox Text="Hello">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="PreviewKeyDown">
                <cmd:EventToCommand 
                     Command="{Binding Close2Command, Mode=OneWay}"
                     PassEventArgsToCommand="True" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>

Window2ViewModel:(具有相同的关闭命令和 EventToCommand 端点)

var _close2Command = new RelayCommand<KeyEventArgs>(p => Close2(p), p => CanClose2(p));

    public void Close2(KeyEventArgs e)
    {
        if (e.Key == Key.Escape)
            Close();               <- Here closes both Window1View and Window2View?
    }

【问题讨论】:

  • 我会说你需要同时发布虚拟机和视图...我怀疑这是一个事件布线问题,但如果没有看到整个图片就无法确定
  • 您需要发布更多代码,尤其是显示事件接线。关闭调用是否会终止您的应用程序?
  • 我已经创建了一个重现问题的解决方案。关键步骤是单击 Win1 按钮,然后在 Win2 上按 Esc(正确关闭),然后单击 hello 文本框,然后按 Esc(现在都关闭?)
  • 显然编辑太多...关键步骤是单击 Win1 按钮,然后在 Win2 上按 Esc(正确关闭),然后再次执行步骤 1,然后单击 hello 文本框获得焦点,然后按 Esc (两个窗口现在都关闭了吗?)
  • Obalix:当从另一个部分调用父级时,它不会终止应用程序。它只是关闭了当前窗口(Window2View)及其父窗口(Window1View),所以一些未知的原因。

标签: wpf mvvm-light


【解决方案1】:

请参阅您的其他线程上的this answer 以获得解决方案。

【讨论】:

  • 是的,因为这个问题很混乱,我认为最好清楚、干净地重新描述问题。一旦你这样做了,答案就会出现。
【解决方案2】:

从 Window2ViewModel 你应该调用 RequestClose 而不是 Close。

这是 Window2ViewModel 的代码

RelayCommand _close2Command;
public ICommand Close2Command
{
    get
    {
        if (_close2Command == null)
        {
            _close2Command = new RelayCommand(param => CloseEx(), param => CanClose());
        }
        return _close2Command;
    }
}

public virtual void CloseEx()
{
    Close();
}

public event Action RequestClose;
public virtual void Close()
{
    if (RequestClose != null)
    {
        *RequestClose();*
    }
}
public virtual bool CanClose()
{
    return true;
}

Window1ViewModel 的代码也应该是:

using GalaSoft.MvvmLight.Command;           
var _runCommand = new RelayCommand(() => Run(), () => CanRun()); 
var vm;

public void Run()               
{                   
    var v = new Window2();                   
    vm = new Window2ViewModel();                   
    vm.RequestClose += CloseV2;                   
    v.DataContext = vm;                   
    v.ShowDialog();               
}                          

public event Action RequestClose;                          
var _closeCommand = new RelayCommand(() => Close(), () => CanClose());    

public void CloseV2()               
{                   
    vm.Close();              
}

public void Close()               
{                   
    if (RequestClose != null)                       
    RequestClose();               
}

尝试理解您的代码。 请注意,在您的代码中,您将 V1.RequestClose 到 V2.RequestClose 的事件绑定到相同的方法 Close。就我而言,我将它们分开,V2.RequestClose 将始终调用 vm.Close。

希望这会有所帮助。

【讨论】:

  • 感谢您的意见。我对此进行了三次检查,但试图减少代码量很可能使它看起来像这样。请参阅上面评论中的链接,我在其中创建了一个重现问题的新解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多