C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

WPF Canvasの上のCanvasが透過状態にならない

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■95573 / inTopicNo.1)  WPF Canvasの上のCanvasが透過状態にならない
  
□投稿者/ つらむ (5回)-(2020/08/18(Tue) 21:46:04)

分類:[.NET 全般] 

お世話になっております。
WPF VS2019です。

フェードイン、フェードアウト用の透明なCanvasを用意したいと思っています。
以下のXAMLを記述して実行しましたが、画面は真っ暗なままでした。

    <Canvas x:Name="fade" Opacity="0.0" Background="Transparent" HorizontalAlignment="Left" VerticalAlignment="Top">
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
            <Canvas x:Name="canvasMain" HorizontalAlignment="Left" VerticalAlignment="Top">
                <Canvas x:Name="canvasLay1" HorizontalAlignment="Left" VerticalAlignment="Top">
                </Canvas>
                <Canvas x:Name="canvasLay2" HorizontalAlignment="Left" VerticalAlignment="Top">
                </Canvas>
            </Canvas>
        </ScrollViewer>
    </Canvas>

Opacityを0にし、BackgroundをTransparentにしているにも関わらず、何故画面は黒くなっているのでしょう。
何かお分かりになられましたら、お教えください。

引用返信 編集キー/
■95574 / inTopicNo.2)  Re[1]: WPF Canvasの上のCanvasが透過状態にならない
□投稿者/ Hongliang (1078回)-(2020/08/19(Wed) 08:50:49)
単に、祖先要素の背景色になっているだけではないでしょうか。
また、HorizontalAlignment/VerticalAlignmentがStretchではなく、Width/Heightも設定していないCanvasは、レイアウトサイズが0になって画面に出てきませんが大丈夫ですか?
引用返信 編集キー/
■95575 / inTopicNo.3)  Re[2]: WPF Canvasの上のCanvasが透過状態にならない
□投稿者/ つらむ (6回)-(2020/08/19(Wed) 09:43:08)
返答ありがとうございます。

仰る通り、以下のソースで祖先色が出ていることがわかりました。


// Opacity="0.5" Background="Red"にして実行後、半透明の赤が出ました。

    <Canvas x:Name="fade" Opacity="0.5" Background="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Height="550" Width="900" >
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
            <Canvas x:Name="canvasMain" HorizontalAlignment="Left" VerticalAlignment="Top">
                <Canvas x:Name="canvasLay1" HorizontalAlignment="Left" VerticalAlignment="Top">
                </Canvas>
                <Canvas x:Name="canvasLay2" HorizontalAlignment="Left" VerticalAlignment="Top">
                </Canvas>
            </Canvas>
        </ScrollViewer>
    </Canvas>

ではどのようにして祖先色を出さず透過させればよいのでしょうか?
ご指導頂けたら幸いです。

引用返信 編集キー/
■95576 / inTopicNo.4)  Re[3]: WPF Canvasの上のCanvasが透過状態にならない
□投稿者/ つらむ (7回)-(2020/08/19(Wed) 09:43:59)
> HorizontalAlignment/VerticalAlignmentがStretchではなく、Width/Heightも設定していないCanvasは、レイアウトサイズが0になって画面に出てきませんが大丈夫ですか?

お気遣いありがとうございます!色々試してみます!

引用返信 編集キー/
■95578 / inTopicNo.5)  Re[3]: WPF Canvasの上のCanvasが透過状態にならない
□投稿者/ Hongliang (1079回)-(2020/08/19(Wed) 09:50:39)
2020/08/19(Wed) 09:51:02 編集(投稿者)

> ではどのようにして祖先色を出さず透過させればよいのでしょうか?

透過した結果、そこに何が映っていることを期待されているのでしょうか。
引用返信 編集キー/
■95579 / inTopicNo.6)  Re[4]: WPF Canvasの上のCanvasが透過状態にならない
□投稿者/ つらむ (8回)-(2020/08/19(Wed) 10:04:49)
以下のコードでCanvas「canvasLay1」にテキストボックスが映りますから、
それが表示されるはずなのです。それが映って欲しいと思います。

            Application.Current.Dispatcher.Invoke((Action)(() =>
            {
		// Marginの設定は別Dispatcherで実行
                TextBox tb = new TextBox();
                tb.Text = "test";
                tb.Name = "te";
                this.canvasLay1.Children.Add(tb);
            }));


どうして映ると言い切れるのかというと言うと、以下のXAMLでは映るからです。

//x:Name="fade"のcanvasが無いバージョン
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
            <Canvas x:Name="canvasMain" HorizontalAlignment="Left" VerticalAlignment="Top">
                <Canvas x:Name="canvasLay1" HorizontalAlignment="Left" VerticalAlignment="Top">
                </Canvas>
                <Canvas x:Name="canvasLay2" HorizontalAlignment="Left" VerticalAlignment="Top">
                </Canvas>
            </Canvas>
        </ScrollViewer>

引用返信 編集キー/
■95580 / inTopicNo.7)  Re[5]: WPF Canvasの上のCanvasが透過状態にならない
□投稿者/ Hongliang (1080回)-(2020/08/19(Wed) 10:38:20)
No95579 (つらむ さん) に返信
> 以下のコードでCanvas「canvasLay1」にテキストボックスが映りますから、
> それが表示されるはずなのです。それが映って欲しいと思います。
> 
>             Application.Current.Dispatcher.Invoke((Action)(() =>
>             {
> 		// Marginの設定は別Dispatcherで実行
>                 TextBox tb = new TextBox();
>                 tb.Text = "test";
>                 tb.Name = "te";
>                 this.canvasLay1.Children.Add(tb);
>             }));

であれば、canvasLay1とfadeは、少なくとも
「fadeが祖先、canvasLay1が子孫」という関係にはできません。
兄弟関係にする必要があります。
例えば
<Canvas>
  <ScrollViewer>
    <Canvas>
      <Canvas x:Name="canvasLay1">
        <TextBox Name="te"/>
      </Canvas>
    </Canvas>
  </ScrollViewer>
  <Canvas x:Name="fade" Opacity="0.5" Background="Red">
  </Canvas>
</Canvas>

fadeは視覚効果だけでマウス等の入力はte等で扱いたい場合、
fadeに IsHitTestVisible="False" を指定するといいです。

引用返信 編集キー/
■95582 / inTopicNo.8)  Re[6]: WPF Canvasの上のCanvasが透過状態にならない
□投稿者/ つらむ (9回)-(2020/08/19(Wed) 18:00:38)
サンプルありがとうございます。映ることが出来ました。

しかし別の問題が持ち上がってしまいました。
それはCanvasのサイズを変更してもスクロールバーが表示されない、スクロール出来ない、というものです。

以下のXAMLに何か不審な点はありますでしょうか?
    <Canvas Opacity="1" Background="Transparent">
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" >
            <Canvas x:Name="canvasMain" HorizontalAlignment="Left" VerticalAlignment="Top">
            </Canvas>
        </ScrollViewer>
        <Canvas x:Name="canvasLay1" HorizontalAlignment="Left" VerticalAlignment="Top">
        </Canvas>
        <Canvas x:Name="canvasLay2" HorizontalAlignment="Left" VerticalAlignment="Top">
        </Canvas>
        <Canvas x:Name="fade" Opacity="0" Background="Transparent">
        </Canvas>
    </Canvas>

Canvasのサイズ変更方法は以下の通りです。
      // baseNmuber は画面サイズを超えるように調整しています
            this.canvasMain.Height = (baseNmuber * 50) + 110;

引用返信 編集キー/
■95585 / inTopicNo.9)  Re[7]: WPF Canvasの上のCanvasが透過状態にならない
□投稿者/ Hongliang (1081回)-(2020/08/20(Thu) 11:21:07)
WPFのレイアウトシステムについて考える必要がありそうです。
WPFでは、計測と配置の2パスで各要素のレイアウトを行います。
どちらもルート要素(Window)から子孫要素に向けて再帰的に行われます。

・計測パス
各要素がどのぐらいの大きさを必要としているかを計測します。
親要素は
「自分はこれだけのサイズを提供できるが、あなたはどれだけのサイズを必要としているか?」
を子要素に問い合わせます。
問い合わされた子要素は、自分に子要素がある場合はさらにそれらに問い合わせたうえで、
自分(およびその子孫要素)が必要とするサイズを計算します。

・配置パス
実際に各要素を配置していきます。
親要素は
「あなたを表示するサイズは計測によってこう決まった。あなたの子要素を配置して」
と要請します。
子要素は、自身が持っている子要素をそれぞれ特定座標に配置していきます。


ScrollViewerは自分の大きさがWidth/Heightなどによって定義されていない場合、
子要素が必要とする大きさが自分の(コンテンツ領域の)大きさになります。
計測パスにおいて親要素から提示されたサイズを参照して、自分が必要とする大きさが
それよりも大きくなる場合(100x100しか親から提供されないのに自分が必要なのは200x200だった)、
スクロールバーの表示が必要になるなと判断したりします。

さて、親要素がCanvasの場合、計測パスで子要素への問い合わせに渡す大きさは「無限大」です。
なので、ScrollViewerは決して親要素であるCanvasより大きいサイズが必要になることはなく、
必然的にスクロールバーの表示も必要なくなります。

ということで、親がCanvasであるなら、ScrollViewerにはなにがしかの方法で自身のサイズを
定義する必要があります。具体的にはWidth/Heightを定義することです。
直値で設定するとウィンドウサイズの変更に追従できなくて困るというのであれば、
バインディングを使用して他の要素のサイズに追従するように作ることになるでしょう。
例えば、
<Canvas x:Name="root">
  <ScrollViewer Width="{Binding Path=ActualWidth, ElementName=root}"
                Height="{Binding Path=ActualHeight, ElementName=root}">

引用返信 編集キー/
■95587 / inTopicNo.10)  Re[8]: WPF Canvasの上のCanvasが透過状態にならない
□投稿者/ つらむ (10回)-(2020/08/20(Thu) 19:53:01)
興味深いお話をありがとうございました。
結論から申し上げると、無事解決することが出来ました。ありがとうございます。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ