0

WPF のウィンドウの不透明度に問題があります。ウィンドウの不透明度を変更したいのですが、子の不透明度はそのままにしておきます。

これが私の現在のコードです:

      Window window = new Window();
  window.WindowStyle = WindowStyle.None;
  window.AllowsTransparency = true;
  window.Background = Brushes.Black;
  window.Opacity = 0.5;
  window.ShowInTaskbar = false;

  double taskBarHeight = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height - System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
  window.Height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height - taskBarHeight;
  window.Width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
  window.Top = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Top;
  window.Left = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Left;

  LoginCtl ctl = new LoginCtl(this);

  window.Content = ctl;
  window.ShowDialog();

子供の不透明度を親よりも高くできないことは理解していますが、回避策はありますか?

4

3 に答える 3

4

ウィンドウの不透明度がどのように機能するかを理解するのに役立つかもしれません。これは、「オーバーレイ」と呼ばれるビデオ アダプタの機能であるハードウェアに実装されています。これは、WS_EX_LAYERED ウィンドウ スタイル フラグとSetLayeredWindowAttributes() api 関数を通じて winapi で公開されます。その関数の MSDN ライブラリ ページに移動して、何が可能かを確認してください。

ビデオ アダプタには、2 つのビデオ メモリ バッファのピクセルを結合できるミキサーがあります。そのミキサーは、アルファ ブレンディングとカラー キーイングの 2 つの効果をサポートします。それぞれ、api 関数の bAlpha および crKey 引数。アルファ ブレンディングは、ここで求めているものです。乗数を使用して 2 つのバッファーのピクセルを結合します。アルファ乗数が低いほど、モニターに送信される最終的なピクセル値に寄与するピクセルが少なくなります。カラー キーイングは、ビデオ処理の一般的なトリックです。天気予報士が天気図の前にいて、ピクセルがカラー キーと一致すると、他のバッファのピクセルに置き換えられます。カラー キーイングは WPF では直接公開されていませんが、Form.TransparencyKey プロパティを使用して Winforms で公開されています。WPF はピクセルごとのアルファを使用し、アルファ コンポーネントを含む 32bpp ピクセルで描画します。

おそらく、なぜこの問題が発生しているのか、winapi が影響をウィンドウに制限していることがわかります。WPF Window クラスと同じように、最上位のウィンドウでなければならないという追加の要件があります。したがって、アルファ ブレンド効果は、ウィンドウ内のすべてのピクセルに適用されます。コントロールのレンダリングに使用されるウィンドウの一部に対して選択的にオフにすることはできません。

リンクされた記事のコメントに注意してください。Windows 8 では、子ウィンドウの指定もサポートされています。これはほぼ確実に、Desk Window Manager である DWM によって行われ、Aero が有効になっている場合に有効になります。ハードウェアではなくソフトウェアで実行されるため、ウィンドウはメモリにレンダリングされ、DWM はピクセルをビデオ アダプターに送信する前にそれらを合成します。その機能は .NET ではまだ公開されておらず、時間がかかります。とにかく、WPFはWinformsのように子ウィンドウを使用しないため、WPFにはあまり役に立ちません。

この問題を解決するために何をする必要があるかを理解するのに十分な紹介です。独自のレイヤリングを行う必要があります。2 つのウィンドウが必要で、一方が他方の上に挟まれています。一番下のウィンドウは、不透明度のみが設定された単純なウィンドウである必要があります。背景を提供します。次に、コントロールを含む別の Window が必要です。その WindowStyle を None に設定し、Background を透明に設定して、下のウィンドウでレンダリングされた背景ピクセルを確認できるようにします。その所有者は下のウィンドウに設定する必要があります。これにより、下のウィンドウが常に上に表示され、ユーザーが下のウィンドウを移動またはサイズ変更したときに移動してサイズを変更する必要があります。

于 2012-11-22T12:37:14.650 に答える
0

私が使用した解決策は、ここにあります。

私がしたことは、グリッドと長方形のみでウィンドウを作成することでした:

    <Grid Name="MainGrid">
    <Rectangle Fill="Gray" Opacity="0.7" />
    </Grid>

そして、コード ビハインドから次の操作を行います。

  LoginWindow win = new LoginWindow();
  win.ShowInTaskbar = false;

  LoginCtl ctl = new LoginCtl(this);
  win.MainGrid.Children.Add(ctl);
  win.ShowDialog();

このように、ウィンドウの背景は透けて見えますが、追加されたコントロールは不透明です。

これが誰かを助けることを願っています!

于 2012-11-26T07:14:57.663 に答える