2009-07-26 13 views
11

ここウィンドウ宣言です:なぜWindowStartupLocation = CenterScreenは画面の中央以外の場所にウィンドウを配置しますか?

<Style 
    x:Key="_windowStyle" 
    TargetType="Window"> 
    <Setter 
     Property="Width" 
     Value="{Binding Path=InitialWindowWidth}" /> 
    <Setter 
     Property="Height" 
     Value="{Binding Path=InitialWindowHeight}" /> 
    <Setter 
     Property="Icon" 
     Value="Resources/MyIcon.ico" /> 
    <Setter 
     Property="Background" 
     Value="{StaticResource _fadedOrangeBrush}" /> 
    <Setter 
     Property="FontSize" 
     Value="11" /> 
</Style> 

考察:

画面がX 1024 1280ウィンドウサイズ(決定される

<Window 
    x:Class="Pse.ExperimentBase.SplashWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Style="{StaticResource _windowStyle}" 
    WindowStartupLocation="CenterScreen" 
    WindowStyle="None"> 

ここスタイル宣言ですInitialWindowWidth、InitialWindowHeightバインディングによる)は800×600です。

ウィンドウが開くと、188,141(左上)と表示されます。これは基本的にはどこにあるべきかの北西です。真の中央値を計算すると、240,212(左、上)になるはずです。

手がかり?

問題が発生するのは、常にの最初のウィンドウです。同じウィンドウの2番目のインスタンスを開くと、正しい場所に表示されます。

別のヒント?

最初のものを開く前に両方のインスタンスを作成すると、が正しい場所に表示されます。

そう...

Window win1 = windowFactory.CreateSplashWindow(); 
win1.Show(); 
Window win2 = windowFactory.CreateSplashWindow(); 
win2.Show(); 
win1.Hide(); 

...オフセットWIN1とWIN2

しかし...

Window win1 = windowFactory.CreateSplashWindow(); 
Window win2 = windowFactory.CreateSplashWindow(); 
win1.Show(); 
win2.Show(); 
win1.Hide(); 

...オフセットWIN1の両方が、WIN2死点を示しています。

だから私の質問は次のとおりです。

ここで何が起こっていますか?


EDIT:

さらに別の手がかり。私が追加した場合...

Width="800" 
Height="600" 

...私のウィンドウ宣言には、オフセットの問題が消えます。ただし、これは私にとっては解決策ではありません。なぜなら、ウィンドウサイズは設定ファイルに保存された設定にする必要があるからです。だからこそ私のスタイルにデータバインディングがあるのです。 (また、幅と高さのデータバインディングはうまくいきます - すべてのウィンドウが正しいサイズとして表示されます)。


EDIT#2:私は、複数のウィンドウインスタンスを作成しても開かない場合

私は、デバッグモード中に幅と高さの確認行なったし、この興味深い結論に達しました任意のウィンドウ、すべてのウィンドウインスタンスの幅と高さのプロパティは "NaN"です。

だけインスタンスの私が、その後開いた場合は、すべてウィンドウインスタンスの幅と高さのプロパティは、突然、有効な数字ではなく、私は開いた窓のちょうど幅と高さです。

これは、最初のウィンドウでShow()が呼び出されるまでWPFがデータバインディングを延期することを示しています。

- >だから今の質問は次のようになります。私は、私は最初のウィンドウが表示さ前に、データ・バインディングを行うにはWPFを強制することはできますか?


編集#3:

私はちょうど提出がマイクロソフトにこの問題に関するバグレポートを提出しました。

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=477598

編集#4:ここにリンクされている回避策

この上ありません本当の解決はまだ、しかし、私はちょうどあなたがダミーのウィンドウを使用して問題を回避できることを確認しました。

  1. "BlankWindow"という新しいXPFウィンドウを作成します(下記のXAMLを参照)。
  2. BlankWindowのインスタンスと、画面上に中央揃えするウィンドウ(FirstWindow)を作成します。
  3. 次のコード・シーケンスを実行します。

...

BlankWindow.Show() 
FirstWindow.Show() 
BlankWindow.Hide() 

を私のダミーウィンドウのXAMLは、これ以上の何物でもありません:私は前に目立っちらつきを見ない

<Window 
    x:Class="Pse.ExperimentBase.Windows.BlankWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="BlankWindow" 
    Height="0" 
    Width="0" 
    WindowStyle="None"> 
    <Grid></Grid> 
</Window> 

"FirstWindow"が開きますので、MSがバグを修正するまで十分な回避策と考えています。

答えて

4

あなたのWidthHeightバインディングは途方もないでしょうか? WidthHeightをまったく設定しないと、ウィンドウが正しい場所に表示されますか?もしそうなら、上記のようにバインディングを設定したときと同じ場所ですか?

すべてが真であれば、バインディングからWidthHeightの値を取得する前に、WPFがウィンドウの位置を計算しているように聞こえます。私はこれを回避する良い方法がわからない - おそらく最初に(XAMLまたはコンストラクタで)WidthHeightを手動で設定し、表示されたらバインディングを設定しますか?

+1

@Andy、あなたは正しいと思います。バインドなしでは、ウィンドウのサイズはデフォルトで907 X 747になり、ウィンドウは座標(188,141)に配置されます。バインディングでは、サイズは800 X 600ですが、座標はまだ(188,141)です。しかし、これは同じ正確なウィンドウの他のインスタンスでは起こりません。あなたは別のテストのアイデアをくれました(上記のEditを参照)。 – devuxer

0

あなたの例では余白の参照がありません。しかし、デザイナでオブジェクトの側をドラッグした後(グリッド内にある場合)、ビジュアルスタジオでアイテムの余白が変更されると、私はしばしばイライラします(余白ではなく幅が変更されると思います)。また、不自然なマージンを持つと、予期しない配置問題が発生する可能性があります。

+0

余白/幅 - 高さの変更の動作は、親コンテナの配置によって異なります。デザイナーの幅を変更している寸法が伸びている場合は、マージンが変更されます。これは、子要素のサイズを親に変更し、子のサイズ変更を許可するという概念です。親のサイズが変わります。 私はそれが迷惑であることに同意します。 – Gusdor

0

かなり古いポストですが、適切な解決策が見つからなかったので別の回避策があります。 ダイアログの場所を手動で計算できます(http://social.msdn.microsoft.com/Forums/eu/wpf/thread/054800c3-56dc-4700-a2fb-d2b79fc9ef9a)。

非常にエレガントではないが、働いている:

public class Controller 
{ 
    private Double CalcCoordinate(Double parentCoordinate, Double parentSize, Double thisSize) 
    { 
      return parentCoordinate + (parentSize - thisSize)/2; 
    } 
    public Controller(Double width, Double height, Window owner) 
    { 
      Width = width; 
      Height = height; 
      Left = CalcCoordinate(owner.Left, owner.Width, Width); 
      Top = CalcCoordinate(owner.Top, owner.Height, Height); 
    } 

public Double Width { get; set; } 
public Double Height { get; set; } 
public Double Left { get; set; } 
public Double Top { get; set; } 

}

はその後、ちょうどこれらのプロパティに、ウィンドウの位置とサイズを結合して、マニュアルにWindowStartupLocationを変更することを忘れないでください。

何らかの理由で、私はちょうど得意ではない、Top/LeftはTwoWayモードでバインドされなければならないが、それがなければ正常に動作することはできない。

0

もう1つの回避策...バインディングにフォールバック値を追加してください。

Width="{Binding Width, FallbackValue=500}" Height="{Binding Height, FallbackValue=500}" 
関連する問題