はじめに
タイトルだけ見ると、ググっておしまいな気がするけど
半日くらい溶かしたので、備忘録として残しておく
ちなみにググってたくさん出てくる「ビルドアクションをリソースに」すれば治る症状とは別のお話
結論
MVVMに則ってViewとViewModelにコードを分けている
View
<Window>
<!-- Windowタグのプロパティは省略 -->
<StackPanel>
<Image Source="{Binding MyImage.Value}" Width="256" Height="256"/>
<Button Command="{Binding ChangeImage}" Content="Change Image!!" />
</StackPanel>
</Window>
MyImageをバインドして、.ValueにはBitmap型を割り当てる
そのビットマップのURIに画像のパスを割り当てる
ViewModel
internal class MainViewModel : INotifyPropertyChanged
{
public ReactiveProperty<BitmapImage> MyImage { get; set; }
public ReactiveCommand ChangeImage { get; }
public MainViewModel()
{
string basePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
Uri baseUri = new Uri(basePath);
Uri imageUri = new Uri(baseUri, "./net6.0-windows/1.bmp");
MyImage = new(new BitmapImage(imageUri));
ChangeImage = new ReactiveCommand().WithSubscribe(() =>
{
var newImageUri = new Uri(baseUri, "./net6.0-windows/2.bmp");
MyImage.Value = new(newImageUri);
});
}
public event PropertyChangedEventHandler? PropertyChanged;
}
ハマったポイントとしては、画像を置いたパスが迷子になった点
実行ファイルが置いてあるところの画像を下記のように指定したが、画像が表示されず
動かないコード
Uri imageUri = new Uri("./1.bmp", UriKind.Relative);
結局丁寧にGetExecutingAssembly().Locationでパスを取得して
new Uri(baseUri, "./net6.0-windows/1.bmp");としてURIを結合した
Uriは書き換えできない
メモリを節約するために、単一のインスタンスのURIを書き換えようと思ったが
画像が表示されている最中はソースを書き換えることができず
仕方なく2つのビットマップをつかっている
_image.UriSource = null;
// nullにはならない
実際の動き
ボタンクリックすることで表示されている画像が切り替わる
詳細
結論が長くなった。ここから詳細の説明
プロジェクトを立ち上げます
.NET 6のWPFアプリケーションをつくり
適当に画像を2枚用意して、ReactivePropertyをインストールする
脱線
おめでとうございます
画像を2枚用意する
実行ファイルと同じ階層に画像を2枚用意する
View側のImageにはサイズを与える
View
<Image Source="{Binding MyImage.Value}" Width="256" Height="256"/>
今回画像サイズは縦横256pxでつくっている
上記記事と違い、自分の環境ではStrechにFillやNoneを入れても、画像は表示された
おわりに
ViewModelについては特筆すべきことはないので、詳細おわり
繰り返しになるが、表示はされてもメモリ食い荒らしそうなコードで気持ちがわるい
ボタンクリック動作のたびにnewを通る。。。
参考
↧