WPF ComboBox DropDown部分出现在错误的位置

时间:2010-01-04 07:34:39

标签: wpf xaml combobox

我在XAML窗口上放了几个ComboBox。当我展开其中任何一个时,DropDown部分会出现在屏幕的左上角。

我使用Visual Studio 2008 C#Express。当我使用Visual Studio 2008(试用版)时,我不记得这种现象,尽管我使用相同的FrameWork(3.5)。

6 个答案:

答案 0 :(得分:1)

这似乎是一个错误。

解决方法:

使用Window.Show()代替自定义逻辑来模拟ShowDialog()行为。

答案 1 :(得分:1)

这似乎是WPF中的一个错误。在我的情况下,我试图在另一个窗口的Loaded事件中打开一个窗口。为了解决这个问题,我将一个计时器设置为触发,然后使用委托打开窗口(无法在计时器事件中打开窗口,因为打开窗口的调用线程必须是STA)。

编辑 - 计时器是不必要的 - 没有看到上面的答案只是将它排在调度员身上......

private delegate void DelegateOpenWindow();
private DelegateOpenWindow m_DelegateOpenWindow;
private Timer loginTimer = new Timer(200);

private void MainWindow1_Loaded(object sender, RoutedEventArgs e)
{
        // create delegate used for asynchronous call
        m_DelegateOpenWindow= new DelegateOpenWindow(this.OpenWindow);
        // start a timer to fire off the open window.
        loginTimer.Elapsed += loginTimer_Elapsed;
        loginTimer.Enabled = true;
}

void loginTimer_Elapsed(object sender, ElapsedEventArgs e)
{
        loginTimer.Enabled = false;
        this.Dispatcher.BeginInvoke(m_DelegateOpenWindow);

}

void OpenWindow()
{
        MyWindow w = new MyWindow();
        w.Owner = this;
        w.ShowDialog();
}

答案 2 :(得分:0)

我昨天开始观察这个(以及其他奇怪的行为怪癖),当时我试图"调整"窗口大小,形状,颜色,并从Window.Loaded事件处理程序调用登录对话框。我在十几个+ MVVM"中的每一个都做得很好。模式应用。昨天,我决定将这个应用程序的代码移到一个整合的代码隐藏基类中,因为预处理已经在所有这些应用程序中变得普遍。当我这样做时,登录对话框中两个ComboBox的下拉突然出现在我的屏幕的左上角。我似乎已经解决了#34;它通过使用以下技术(您的里程可能会有所不同):

    protected void WindowBaseLoadedHandler(object sender, RoutedEventArgs e)
    {
...non-essential lines of code removed...

        if (DataContext != null)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
            {
                /*----------------------------------------------------------------------
                 * Do we have a View Model? If so, perform standard VM Initialization...
                 *---------------------------------------------------------------------*/
                this.IsEnabled = false;

                LoginDlg loginDlg = new LoginDlg();
                loginDlg.ShowDialog();

                if (!loginDlg.Success)
                {
                    /*-----------------------------------
                     * Log on failed -- terminate app...
                     *----------------------------------*/
                    ...termination logic removed...
                }

                this.IsEnabled = true;
            }));
        }

WindowBaseLoadedHandler是Loaded事件处理程序。 LoginDlg是一个WPF应用程序,其对话框包含两个ComboBox。

回顾:在将代码合并到基类的Loaded事件处理程序之后,ComboBox的下拉列表出现在我的屏幕的左上角。一旦我将逻辑包装到Dispatcher.BeginInvoke调用中,就会返回相应的ComboBox行为,其中包含当前项下面的列表。

我怀疑WPF需要应用程序从Loaded事件返回以完成布局系统的初始化。这并没有完全解释为什么它以前有效,但我不得不排好我追捕那个"为什么"在未来的某个下雨天,庆祝克服今天的最新障碍。

无论如何,我希望有人能够发现这一点。

答案 3 :(得分:0)

我正在使用最新的.Net 4.5和WPF框架,我仍然遇到这个问题。我注意到的一件事是它只发生在附加调试器时。如果未附加调试器,一切正常。

答案 4 :(得分:0)

我在Visual Studio 2019上遇到了同样的问题。 使用window.Show()可以帮助您,但可能会破坏您的设计。 解决方案是异步打开窗口。

var yourDialog= new YourDialog();
yourDialog.Owner = this;
TaskCompletionSource<bool?> completion = new TaskCompletionSource<bool?>();
this.Dispatcher.BeginInvoke(new Action(() => 
completion.SetResult(yourDialog.ShowDialog())));
bool? result = await completion.Task;

您还可以通过使用扩展方法来创建更优雅的解决方案:

public static class AsyncWindowExtension
{
    public static Task<bool?> ShowDialogAsync(this Window self)
    {
        if (self == null) throw new ArgumentNullException("self");

        TaskCompletionSource<bool?> completion = new TaskCompletionSource<bool?>();
        self.Dispatcher.BeginInvoke(new Action(() => completion.SetResult(self.ShowDialog())));

        return completion.Task;
    }
}

您可以像这样使用它:

await dlgReview.ShowDialogAsync();

答案 5 :(得分:-1)

这是WPF中的一个错误(不是唯一一个,我害怕)。它发生在我在Loaded Event中打开另一个窗口时,例如:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Window selectionWindow = new SelectionWindow();
    bool? result = selectionWindow.ShowDialog();
    if (result == true)
        RecordChanged();
}

我已经找到了一份工作。