質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

1345閲覧

WPF C# ImageSourceを利用しているからか、画像がロックされてしまう

nodoita

総合スコア7

.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

1クリップ

投稿2023/06/14 01:42

編集2023/06/15 01:05

お世話になります。
色々なところで調べたものを利用させて頂いておりますが、分からないため教えてください。

実現したいこと

  • imageフォルダにある画像をロックしないようにしたい
  • リストビューに画像をドロップしたら、自動で画像が追加表示したい
  • MainWindowに全面ImageView、SubWindowに画像一覧をリスト表示をロックをかけずにしたい
  • 追加した画像名がカブる場合、警告を表示して上書きするか選びたい
  • リストビューにボタンを表示し、imageフォルダにある画像を削除できるようにしたい

とりあえず、画像をロックしない方法と、画面表示を更新する方法(Bindingが理解できてない?)を知りたいです。

前提

リストビューを表示し、ドロップした画像をアプリのフォルダにjpg変換してコピーします。
リストビューのテキストボックスを編集したら
メタデータのタイトルに書き込む予定となっています。

ドロップしてアプリのimageフォルダにjpgとしてコピーは出来ましたが、
BindingでImageに直接表示しているためか
ロックがかかってしまい編集や削除が出来ない状況になります。

上手くいかないこと

・ドロップした画像が追加表示されない
・ドロップした画像も、元々imageフォルダにあった画像もロックがかかり削除や編集ができない。

・TextBox_PreviewTextInputが確定時以外で動く(アルファベッド1文字いれたら動く、ひらかな入力で未確定だと問題なし)
→できたらフォーカスが外れたときに動かしたい

該当のソースコード

SubWindow.xaml

1 <Grid> 2 <Grid.ColumnDefinitions> 3 <ColumnDefinition Width="*"/> 4 <ColumnDefinition Width="2*"/> 5 </Grid.ColumnDefinitions> 6 <Grid.RowDefinitions> 7 <RowDefinition Height="8*"/> 8 <RowDefinition Height="*"/> 9 </Grid.RowDefinitions> 10 <ListView x:Name="SubList" Grid.Column="0" SelectionChanged="SubList_SelectionChanged" AllowDrop="True" DragOver="File_DragOver" Drop="File_Drop"> 11 <ListView.View> 12 <GridView> 13 <!--<GridViewColumn 14 Width="200" 15 DisplayMemberBinding="{Binding FileTitle}" 16 Header="タイトル" />--> 17 <GridViewColumn Width="200" Header="タイトル"> 18 <GridViewColumn.CellTemplate> 19 <DataTemplate> 20 <TextBox Padding="1" Width="200" Text="{Binding Path=FileTitle}" TextWrapping="Wrap" PreviewTextInput="TextBox_PreviewTextInput"/> 21 </DataTemplate> 22 </GridViewColumn.CellTemplate> 23 </GridViewColumn> 24 25 <GridViewColumn Width="50" Header="ファイル名" 26 DisplayMemberBinding="{Binding FileName}"/> 27 28 </GridView> 29 </ListView.View> 30 </ListView> 31 <ListView x:Name="SubListPic" Grid.Column="1" ItemsSource="{Binding FileDatas}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="SubListPic_SelectionChanged" AllowDrop="True" DragOver="File_DragOver" Drop="File_Drop"> 32 <ListView.ItemsPanel> 33 <ItemsPanelTemplate> 34 <WrapPanel/> 35 </ItemsPanelTemplate> 36 </ListView.ItemsPanel> 37 <ListView.ItemTemplate> 38 <DataTemplate> 39 <Grid Width="150" Height="150"> 40 <TextBlock Text="{Binding FileTitle}"></TextBlock> 41 <Image Source="{Binding FilePath}"></Image> 42 </Grid> 43 </DataTemplate> 44 </ListView.ItemTemplate> 45 </ListView>

SubWindow.xaml.cs

1 public partial class SubWindow : Window 2 { 3 4 public static List<FileData> FileDatas = new List<FileData>(); 5 public static bool SelectChangeNow=false; 6 7 8 public SubWindow() 9 { 10 InitializeComponent(); 11 SubList.ItemsSource = FileDatas; 12 SubListPic.ItemsSource = FileDatas; 13 14 DataImport(); 15 16 } 17 18 19 public void DataImport() 20 { 21 string DefoPath = System.AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\\') + "\\image\\"; 22 23 string[] filesFullPath = System.IO.Directory.GetFiles(@DefoPath, "*.jpg", System.IO.SearchOption.TopDirectoryOnly); 24 foreach (string fileFullPath in filesFullPath) 25 { 26 string fileName = System.IO.Path.GetFileName(fileFullPath); 27 string Title = ""; 28 using (var fs = new FileStream(fileFullPath, FileMode.Open, FileAccess.ReadWrite)) 29 { 30 // ファイルを読み込み、BitmapFrameを作成する 31 var f = BitmapFrame.Create(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand); 32 // メタデータを編集するためのインスタンスを作成する 33 var meta = f.CreateInPlaceBitmapMetadataWriter(); 34 // メタデータの変更を元のファイルに書き込む 35 meta.TrySave(); 36 } 37 38 //フルパスを出力 39 Console.WriteLine("ファイル = {0}", fileFullPath); 40 41 //ファイル名のみを出力 42 Console.WriteLine("ファイル = {0}", fileName); 43 FileDatas.Add(new FileData(Title, fileName,fileFullPath)); 44 } 45 } 46 47 private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) 48 { 49 var textData = sender as TextBox; 50 if (textData == null) return; 51 52 MessageBox.Show(textData.Text); 53 } 54 55 private void File_Drop(object sender, DragEventArgs e) 56 { 57 if (e.Data.GetDataPresent(DataFormats.FileDrop) == false) 58 return; 59 var originalPath = ((string[])e.Data.GetData(DataFormats.FileDrop)); 60 var outputPath = System.AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\\') + "\\image\\"; 61 var NGList = new List<string>(); 62 63 for (var i = 0; i < originalPath.Length; i++) 64 { 65 var fileNameEx = Path.GetFileName(originalPath[i]);//FileName.bmp 拡張子付きファイル名 66 var fileName = Path.GetFileNameWithoutExtension(originalPath[i]);//FileName 67 var extension = Path.GetExtension(originalPath[i]);//拡張子「.jpg/.jpeg/.png/.bmp」 68 if (extension.ToLower() != ".jpg" && extension.ToLower() != ".jpeg" && 69 extension.ToLower() != ".bmp" && extension.ToLower() != ".png") 70 { 71 NGList.Add(fileName); 72 continue; 73 74 } 75 // 入出力するファイルを開く 76 var fsin = new FileStream(originalPath[i], FileMode.Open, FileAccess.ReadWrite); 77 BitmapFrame f = BitmapFrame.Create(fsin, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand); 78 var meta = f.Metadata.Clone() as BitmapMetadata ?? new BitmapMetadata("jpg"); 79 // JPEGファイルの出力 80 var enc = new JpegBitmapEncoder(); 81 enc.Frames.Add(BitmapFrame.Create(f, f.Thumbnail, meta, f.ColorContexts)); 82 83 var fsout = new System.IO.FileStream(outputPath + fileName + ".jpg", FileMode.Create); 84 enc.Save(fsout); 85 86 fsin.Close(); 87 fsout.Close(); 88 fsin=null; 89 fsout=null; 90 } 91 92 string NGListData = ""; 93 if (NGList.Count != 0) { 94 for(var i = 0; i < NGList.Count; i++) 95 { 96 NGListData = NGListData + NGList[i] + "\n"; 97 } 98 MessageBox.Show(NGListData + "のファイルは読めませんでした"); 99 } 100 101 DataImport(); 102 103 } 104} 105

FileData.cs

1namespace TEST 2{ 3 4 public class FileData : INotifyPropertyChanged 5 { 6 private string fileTitle = "default"; 7 public string FileTitle 8 { 9 get { return fileTitle; } 10 set 11 { 12 if (fileTitle != value) 13 { 14 fileTitle = value; 15 OnPropertyChanged(); 16 } 17 } 18 } 19 20 private string fileName = "default"; 21 public string FileName 22 { 23 get { return fileName; } 24 set 25 { 26 if (fileName != value) 27 { 28 fileName = value; 29 OnPropertyChanged(); 30 } 31 } 32 } 33 34 private string filePath = "default"; 35 public string FilePath 36 { 37 get { return filePath; } 38 set 39 { 40 if (filePath != value) 41 { 42 filePath = value; 43 OnPropertyChanged(); 44 } 45 } 46 } 47 48 49 public FileData(string fileTitle, string fileName, string filePath) 50 { 51 FileTitle = fileTitle; 52 FileName = fileName; 53 FilePath = filePath; 54 } 55 56 public event PropertyChangedEventHandler PropertyChanged; 57 58 protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 59 { 60 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 61 } 62 63 public override string ToString() 64 { 65 return $"{FileName}"; 66 } 67 68 } 69}

追記

 追記長すぎたので削除

補足情報(FW/ツールのバージョンなど)

Visualstudio2022
.NET 6.0 C#

回答頂いたソースについて

TN8001様、回答ありがとうございます!
BindingとMVVMが難しくて中々理解が難しいですが、勉強頑張ります。

動作確認をしたかったため、VisualStudioで新規作成し
ソースをコピペしてビルドしてみましたが、エラーが出て実行できません。
NugetではMVVM追加済みです。
(見づらいため本文にもエラー内容を追記しています)

1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.ClassUsingAttributeInsteadOfInheritanceAnalyzer のインスタンスは C:\Users\test.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。
~同じようなエラーが数個~

VisualStudio2022でMVVM使うために、C#のバージョン?を上げないといけないとみて
TEST.csprojに<LangVersion>9.0</LangVersion>を追加してみましたが、ビルド出来ない症状は変わりませんでした。
以下のようなエラーも出ています。

VisualStudio 2022 Version17.3.4を利用してます。
度々申し訳ありませんが、何か分かりますでしょうか。

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YAmaGNZ

2023/06/14 06:21

「WPF C# ImageSource ファイルロック」とでも検索してみてはどうでしょう?
nodoita

2023/06/14 08:05

YAmaGNZ様 回答ありがとうございます。 //lock less bitmap MemoryStream data = new MemoryStream(File.ReadAllBytes(dst_image_path)); WriteableBitmap wbmp = new WriteableBitmap(BitmapFrame.Create(data)); data.Close(); this.Dispatcher.Invoke((Action)(() => { BitmapImage bmp = new BitmapImage(); bmp.BeginInit(); bmp.CacheOption = BitmapCacheOption.OnLoad; bmp.UriSource = new Uri(dst_image_path); bmp.EndInit(); WriteableBitmap wbmp = new WriteableBitmap(bmp); this.MainImage.Source = wbmp; })); 上記のような方法を見つけましたが、 Bindingがあまり良く分かっておらずどのように修正すべきか分からない状況です。 メモリに読ませて描画させれば画像ロックしないことは分かったのですが それをどう「FileData.cs」や「SubWindow.xaml.cs」に記載すれば良いのか分からないのです。 リストビューで反映するようにするために <Image Source="{Binding FilePath}"></Image> 上記のように設定していて自動で画像が表示されています。 画像ドロップ時に表示されないこと、画像ファイルがロックされることを除けば、思った通りの動作をしています。
YAmaGNZ

2023/06/14 08:31

FileDataクラスにてFilePathが設定された時などに画像を読み込みロックされないようにして、読み込んが画像をBitmapImageといったプロパティで公開しバインドすればいいのでは? 検索したらそういった方法の解説ページが見つかりましたしConverterを用意してロックを回避する方法を解説するページもありました。
guest

回答2

0

以降の質問でだいぶ全貌が分かったので、回答しなおします。

  • SubWindowをダイアログに変更
  • ListViewDataGridに変更
  • ViewModelを分離しやすい構造に変更
  • 文字数がタイトなためコメントなし

MainWindow

xml

1<Window 2 x:Class="Qt6uox4f1iujybm.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Qt6uox4f1iujybm" 6 Title="MainWindow" 7 SizeToContent="WidthAndHeight"> 8 <Window.Resources> 9 <local:ImageConverter x:Key="ImageConverter" /> 10 </Window.Resources> 11 12 <DockPanel> 13 <ToolBar DockPanel.Dock="Top"> 14 <Button MinWidth="128" Click="OpenSelectPictDialog_Click" Content="背景画像の選択" /> 15 </ToolBar> 16 <Grid> 17 <Image 18 Width="1000" 19 Height="800" 20 HorizontalAlignment="Left" 21 VerticalAlignment="Top" 22 Source="{Binding Pict.SelectedItem.FilePath, Converter={StaticResource ImageConverter}}" 23 StretchDirection="DownOnly" /> 24 </Grid> 25 </DockPanel> 26</Window>

cs

1using System; 2using System.Globalization; 3using System.IO; 4using System.Windows; 5using System.Windows.Data; 6using System.Windows.Media.Imaging; 7 8namespace Qt6uox4f1iujybm; 9 10 11public partial class MainWindow : Window 12{ 13 public MainWindow() 14 { 15 InitializeComponent(); 16 17 var imageFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "image"); 18 DataContext = new ViewModel { Pict = new(imageFolder), }; 19 } 20 21 private void OpenSelectPictDialog_Click(object sender, RoutedEventArgs e) 22 => new SelectPictDialog { DataContext = DataContext, Owner = this, }.ShowDialog(); 23} 24 25public class ImageConverter : IValueConverter 26{ 27 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 28 { 29 try 30 { 31 using var fs = new FileStream((string)value, FileMode.Open); 32 var decoder = BitmapDecoder.Create(fs, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); 33 var bmp = new WriteableBitmap(decoder.Frames[0]); 34 bmp.Freeze(); 35 return bmp; 36 } 37 catch { } 38 return DependencyProperty.UnsetValue; 39 } 40 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); 41}

SelectPictDialog

xml

1<Window 2 x:Class="Qt6uox4f1iujybm.SelectPictDialog" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Qt6uox4f1iujybm" 6 Title="背景画像の選択" 7 Width="800" 8 Height="450" 9 AllowDrop="True" 10 DragOver="File_DragOver" 11 Drop="File_Drop" 12 WindowStartupLocation="CenterOwner"> 13 <Window.Resources> 14 <local:ImageConverter x:Key="ImageConverter" /> 15 </Window.Resources> 16 17 <DockPanel> 18 <StackPanel HorizontalAlignment="Right" DockPanel.Dock="Bottom" Orientation="Horizontal"> 19 <Button 20 MinWidth="80" 21 Margin="8" 22 Click="Ok_Button_Click" 23 Command="{Binding Pict.ApplyCommand}" 24 CommandParameter="{Binding Pict.Items/}" 25 Content="OK" 26 IsDefault="True" /> 27 <Button MinWidth="80" Margin="8" Content="Cancel" IsCancel="True" /> 28 <Button 29 MinWidth="80" 30 Margin="8" 31 Command="{Binding Pict.ApplyCommand}" 32 CommandParameter="{Binding Pict.Items/}" 33 Content="適用" /> 34 </StackPanel> 35 <Grid> 36 <Grid.ColumnDefinitions> 37 <ColumnDefinition /> 38 <ColumnDefinition Width="4" /> 39 <ColumnDefinition /> 40 </Grid.ColumnDefinitions> 41 42 <DataGrid AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Pict.Items}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 43 <DataGrid.Columns> 44 <DataGridTextColumn Width="200" Binding="{Binding FileTitle}" Header="タイトル" /> 45 <DataGridTextColumn Width="*" Binding="{Binding FileName}" Header="ファイル名" IsReadOnly="True"> 46 <DataGridTextColumn.CellStyle> 47 <Style TargetType="DataGridCell"> 48 <Setter Property="ToolTip" Value="{Binding FileName}" /> 49 </Style> 50 </DataGridTextColumn.CellStyle> 51 </DataGridTextColumn> 52 <DataGridTemplateColumn> 53 <DataGridTemplateColumn.CellTemplate> 54 <DataTemplate> 55 <Button Command="{Binding DataContext.Pict.DeleteCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding}" Content="削除" /> 56 </DataTemplate> 57 </DataGridTemplateColumn.CellTemplate> 58 </DataGridTemplateColumn> 59 </DataGrid.Columns> 60 </DataGrid> 61 62 <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" /> 63 64 <ListBox Grid.Column="2" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Pict.Items}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 65 <ListBox.ItemsPanel> 66 <ItemsPanelTemplate> 67 <WrapPanel /> 68 </ItemsPanelTemplate> 69 </ListBox.ItemsPanel> 70 <ListBox.ItemTemplate> 71 <DataTemplate> 72 <StackPanel MaxWidth="150"> 73 <Image MaxHeight="150" Source="{Binding FilePath, Converter={StaticResource ImageConverter}}" /> 74 <TextBlock Text="{Binding FileTitle}" TextTrimming="CharacterEllipsis" /> 75 </StackPanel> 76 </DataTemplate> 77 </ListBox.ItemTemplate> 78 </ListBox> 79 </Grid> 80 </DockPanel> 81</Window>

cs

1using System; 2using System.IO; 3using System.Linq; 4using System.Windows; 5 6namespace Qt6uox4f1iujybm; 7 8 9public partial class SelectPictDialog : Window 10{ 11 private static readonly string[] supportedFormats = { ".jpg", ".jpeg", ".bmp", ".png", }; 12 13 public SelectPictDialog() => InitializeComponent(); 14 15 private void File_DragOver(object sender, DragEventArgs e) 16 { 17 e.Effects = e.Data.GetDataPresent(DataFormats.FileDrop, true) ? DragDropEffects.Copy : DragDropEffects.None; 18 e.Handled = true; 19 } 20 21 private void File_Drop(object sender, DragEventArgs e) 22 { 23 if (!e.Data.GetDataPresent(DataFormats.FileDrop)) return; 24 25 var files = (string[])e.Data.GetData(DataFormats.FileDrop); 26 27 var ok = files.Where(x => supportedFormats.Contains(Path.GetExtension(x).ToLower())); 28 foreach (var path in ok) 29 { 30 ((ViewModel)DataContext).Pict?.AddItem(path, IsOverwrite); 31 32 bool IsOverwrite() 33 { 34 var msg = $"同名のファイルが既にあります。\n上書きしますか?\n\n{path}"; 35 var r = MessageBox.Show(this, msg, "", MessageBoxButton.YesNo, MessageBoxImage.Warning); 36 return r == MessageBoxResult.Yes; 37 } 38 } 39 40 var ng = files.Where(x => !supportedFormats.Contains(Path.GetExtension(x).ToLower())); 41 if (ng.Any()) MessageBox.Show(this, $"{string.Join("\n", ng)}\nのファイルは読めませんでした"); 42 } 43 private void Ok_Button_Click(object sender, RoutedEventArgs e) => DialogResult = true; 44}

ViewModel&Model

cs

1using System; 2using System.Collections.ObjectModel; 3using System.IO; 4using System.Linq; 5using System.Windows.Media.Imaging; 6using CommunityToolkit.Mvvm.ComponentModel; 7using CommunityToolkit.Mvvm.Input; 8 9namespace Qt6uox4f1iujybm; 10 11 12public partial class ViewModel 13{ 14 public PictModel? Pict { get; init; } 15} 16 17public partial class PictModel : ObservableObject 18{ 19 public ObservableCollection<PictItem> Items { get; } = new(); 20 [ObservableProperty] private PictItem? selectedItem; 21 22 private readonly string folder; 23 24 public PictModel(string folder) 25 { 26 this.folder = folder; 27 Directory.CreateDirectory(folder); 28 foreach (var path in Directory.EnumerateFiles(folder, "*.jpg", SearchOption.TopDirectoryOnly)) 29 Items.Add(new(path)); 30 } 31 32 [RelayCommand] private void Apply(PictItem? item) => SelectedItem = item; 33 [RelayCommand] 34 private void Delete(PictItem item) 35 { 36 Items.Remove(item); 37 File.Delete(item.FilePath); 38 } 39 40 public void AddItem(string path, Func<bool> isOverwrite) 41 { 42 var fileName = Path.GetFileNameWithoutExtension(path); 43 var outPath = Path.Combine(folder, $"{fileName}.jpg"); 44 45 if (File.Exists(outPath)) 46 { 47 if (!isOverwrite()) return; 48 Items.Remove(Items.FirstOrDefault(x => x.FilePath == outPath)!); 49 } 50 51 using (var fsin = new FileStream(path, FileMode.Open, FileAccess.ReadWrite)) 52 using (var fsout = new FileStream(outPath, FileMode.Create, FileAccess.Write)) 53 { 54 var f = BitmapFrame.Create(fsin, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand); 55 var meta = f.Metadata.Clone() as BitmapMetadata ?? new BitmapMetadata("jpg"); 56 var enc = new JpegBitmapEncoder(); 57 enc.Frames.Add(BitmapFrame.Create(f, f.Thumbnail, meta, f.ColorContexts)); 58 enc.Save(fsout); 59 } 60 61 Items.Add(new(outPath)); 62 } 63} 64 65public partial class PictItem : ObservableObject 66{ 67 [ObservableProperty] private string? fileTitle; 68 public string FilePath { get; } 69 public string FileName => Path.GetFileNameWithoutExtension(FilePath); 70 71 public PictItem(string filePath) 72 { 73 FilePath = filePath; 74 using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); 75 var f = BitmapFrame.Create(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand); 76 var meta = f.Metadata as BitmapMetadata; 77 fileTitle = meta?.Title; 78 } 79 80 partial void OnFileTitleChanged(string? value) 81 { 82 using var fsin = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); 83 var decoder = new JpegBitmapDecoder(fsin, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); 84 var frame = decoder.Frames[0]; 85 var meta = frame.CreateInPlaceBitmapMetadataWriter(); 86 meta.Title = value; 87 88 if (!meta.TrySave()) 89 { 90 using var fsout = new FileStream(FilePath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite); 91 var encoder = new JpegBitmapEncoder(); 92 foreach (var cloneFrame in decoder.Frames) encoder.Frames.Add(BitmapFrame.Create(cloneFrame)); 93 ((BitmapMetadata)encoder.Frames[0].Metadata).Title = value; 94 encoder.Save(fsout); 95 } 96 } 97}

NuGet Gallery | CommunityToolkit.Mvvm 8.2.0

アプリ画像

投稿2023/07/11 12:45

TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

imageフォルダにある画像をロックしないようにしたい

Image.Sourceに文字列でバインドすると、残念ながらロックしてしまいます。
いくつか解決法はありますが、こちらでどうでしょう?
WPFで画像表示時にファイルをロックしないようにしたい - かずきのBlog@hatena

リストビューに画像をドロップしたら、自動で画像が追加表示したい

増減のあるコレクションはListでなく、ObservableCollectionを使用してください。
ObservableCollection<T> クラス (System.Collections.ObjectModel) | Microsoft Learn

追加した画像名がカブる場合、警告を表示して上書きするか選びたい

ここまでできているなら、そう難しいとも思えませんが...
上書きの際はFileDataを丸ごと入れ替える(FileDatasからRemoveしてAdd)か、FilePathPropertyChangedを叩かないと画像が変わらないです。

リストビューにボタンを表示し、imageフォルダにある画像を削除できるようにしたい

CellTemplateを使用してください。

TextBox_PreviewTextInputが確定時以外で動く
できたらフォーカスが外れたときに動かしたい

普通にバインドしてください。


MainWindow

xml

1<Window x:Class="Qt6uox4f1iujybm.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Width="600" Height="450"> 2 <DockPanel> 3 <ToggleButton Content="Open SubWindow" DockPanel.Dock="Top" IsChecked="{Binding IsSubWindowShown}" /> 4 <Image Source="{Binding Items/FilePath, Converter={StaticResource ImageConverter}}" /> 5 </DockPanel> 6</Window>

cs

1using System; 2using System.Globalization; 3using System.IO; 4using System.Windows; 5using System.Windows.Data; 6using System.Windows.Media.Imaging; 7 8namespace Qt6uox4f1iujybm; 9 10 11public partial class MainWindow : Window 12{ 13 private readonly SubWindow subWindow; // GCよけ 14 15 public MainWindow() 16 { 17 InitializeComponent(); 18 19 var imageFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "image"); 20 var vm = new ViewModel(imageFolder); 21 DataContext = vm; 22 subWindow = new SubWindow(vm); 23 } 24} 25 26public class ImageConverter : IValueConverter 27{ 28 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 29 { 30 try 31 { 32 using var fs = new FileStream((string)value, FileMode.Open); 33 var decoder = BitmapDecoder.Create(fs, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); 34 var bmp = new WriteableBitmap(decoder.Frames[0]); 35 bmp.Freeze(); 36 return bmp; 37 } 38 catch { } 39 return DependencyProperty.UnsetValue; 40 } 41 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException(); 42}

SubWindow

xml

1<Window 2 x:Class="Qt6uox4f1iujybm.SubWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Title="SubWindow" 6 Width="800" 7 Height="450" 8 AllowDrop="True" 9 Closing="Window_Closing" 10 DragOver="File_DragOver" 11 Drop="File_Drop" 12 Visibility="{Binding IsSubWindowShown, Mode=TwoWay, Converter={StaticResource BooleanToVisibilityConverter}}"> 13 <DockPanel> 14 <StatusBar DockPanel.Dock="Bottom"> 15 <StatusBarItem> 16 <TextBlock Text="{Binding Items/FilePath}" /> 17 </StatusBarItem> 18 </StatusBar> 19 20 <Grid> 21 <Grid.ColumnDefinitions> 22 <ColumnDefinition /> 23 <ColumnDefinition Width="5" /> 24 <ColumnDefinition Width="2*" /> 25 </Grid.ColumnDefinitions> 26 27 <ListView IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Items}"> 28 <ListView.View> 29 <GridView> 30 <GridViewColumn Width="200" Header="タイトル"> 31 <GridViewColumn.CellTemplate> 32 <DataTemplate> 33 <TextBox Width="200" Padding="1" Text="{Binding FileTitle}" TextWrapping="Wrap" /> 34 </DataTemplate> 35 </GridViewColumn.CellTemplate> 36 </GridViewColumn> 37 <GridViewColumn DisplayMemberBinding="{Binding FileName}" Header="ファイル名" /> 38 <GridViewColumn> 39 <GridViewColumn.CellTemplate> 40 <DataTemplate> 41 <Button Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" CommandParameter="{Binding}" Content="削除" /> 42 </DataTemplate> 43 </GridViewColumn.CellTemplate> 44 </GridViewColumn> 45 </GridView> 46 </ListView.View> 47 </ListView> 48 49 <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" /> 50 51 <ListView Grid.Column="2" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Items}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 52 <ListView.ItemsPanel> 53 <ItemsPanelTemplate> 54 <WrapPanel /> 55 </ItemsPanelTemplate> 56 </ListView.ItemsPanel> 57 <ListView.ItemTemplate> 58 <DataTemplate> 59 <Grid Width="150" Height="150"> 60 <TextBlock Text="{Binding FileTitle}" /> 61 <Image Source="{Binding FilePath, Converter={StaticResource ImageConverter}}" /> 62 </Grid> 63 </DataTemplate> 64 </ListView.ItemTemplate> 65 </ListView> 66 </Grid> 67 </DockPanel> 68</Window>

cs

1using System; 2using System.ComponentModel; 3using System.IO; 4using System.Linq; 5using System.Windows; 6 7namespace Qt6uox4f1iujybm; 8 9 10public partial class SubWindow : Window 11{ 12 private static readonly string[] SupportedFormats = { ".jpg", ".jpeg", ".bmp", ".png" }; 13 14 private readonly ViewModel viewModel; 15 16 public SubWindow(ViewModel viewModel) 17 { 18 InitializeComponent(); 19 DataContext = this.viewModel = viewModel; 20 } 21 22 private void File_DragOver(object sender, DragEventArgs e) 23 { 24 e.Effects = e.Data.GetDataPresent(DataFormats.FileDrop, true) ? DragDropEffects.Copy : DragDropEffects.None; 25 e.Handled = true; 26 } 27 28 private void File_Drop(object sender, DragEventArgs e) 29 { 30 if (!e.Data.GetDataPresent(DataFormats.FileDrop)) return; 31 32 var files = (string[])e.Data.GetData(DataFormats.FileDrop); 33 34 var ok = files.Where(x => SupportedFormats.Contains(Path.GetExtension(x).ToLower())); 35 foreach (var path in ok) 36 { 37 viewModel.AddItem(path, IsOverwrite); 38 39 bool IsOverwrite() 40 { 41 var msg = $"同名のファイルが既にあります。\n上書きしますか?\n\n{path}"; 42 var r = MessageBox.Show(this, msg, "", MessageBoxButton.YesNo, MessageBoxImage.Warning); 43 return r == MessageBoxResult.Yes; 44 } 45 } 46 47 var ng = files.Where(x => !SupportedFormats.Contains(Path.GetExtension(x).ToLower())); 48 if (ng.Any()) MessageBox.Show(this, $"{string.Join("\n", ng)}\nのファイルは読めませんでした"); 49 } 50 51 private void Window_Closing(object sender, CancelEventArgs e) 52 { 53 e.Cancel = true; 54 Hide(); 55 } 56}

ViewModel&Model

cs

1using System; 2using System.Collections.Generic; 3using System.Collections.ObjectModel; 4using System.Diagnostics; 5using System.IO; 6using System.Linq; 7using System.Windows.Media.Imaging; 8using CommunityToolkit.Mvvm.ComponentModel; 9using CommunityToolkit.Mvvm.Input; 10 11namespace Qt6uox4f1iujybm; 12 13 14public partial class ViewModel : ObservableObject 15{ 16 public ObservableCollection<Item> Items { get; } = new(); 17 18 [ObservableProperty] private bool isSubWindowShown; 19 20 21 private readonly string folder; 22 23 public ViewModel(string folder) 24 { 25 this.folder = folder; 26 Directory.CreateDirectory(folder); 27 ImportFiles(Directory.EnumerateFiles(folder, "*.jpg", SearchOption.TopDirectoryOnly)); 28 } 29 30 [RelayCommand] 31 private void Delete(Item item) 32 { 33 Items.Remove(item); 34 File.Delete(item.FilePath); 35 } 36 37 public void ImportFiles(IEnumerable<string> paths) 38 { 39 foreach (var path in paths) Items.Add(new(path)); 40 } 41 42 public void AddItem(string path, Func<bool> isOverwrite) 43 { 44 var fileName = Path.GetFileNameWithoutExtension(path); 45 var outPath = Path.Combine(folder, $"{fileName}.jpg"); 46 if (File.Exists(outPath)) 47 { 48 if (!isOverwrite()) return; 49 Items.Remove(Items.FirstOrDefault(x => x.FilePath == outPath)!); 50 } 51 52 using (var fsin = new FileStream(path, FileMode.Open, FileAccess.ReadWrite)) 53 using (var fsout = new FileStream(outPath, FileMode.Create, FileAccess.Write)) 54 { 55 var f = BitmapFrame.Create(fsin, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand); 56 var meta = f.Metadata.Clone() as BitmapMetadata ?? new BitmapMetadata("jpg"); 57 var enc = new JpegBitmapEncoder(); 58 enc.Frames.Add(BitmapFrame.Create(f, f.Thumbnail, meta, f.ColorContexts)); 59 enc.Save(fsout); 60 } 61 62 Items.Add(new(outPath)); 63 } 64} 65 66public partial class Item : ObservableObject 67{ 68 [ObservableProperty] private string? fileTitle; 69 public string FilePath { get; } 70 public string FileName => Path.GetFileNameWithoutExtension(FilePath); 71 72 public Item(string filePath) 73 { 74 FilePath = filePath; 75 using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); 76 fileTitle = (BitmapFrame.Create(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand).Metadata as BitmapMetadata)?.Title; 77 } 78 79 partial void OnFileTitleChanged(string? value) 80 { 81 // なぜかタイトルと件名両方入っちゃう?? 82 // 事前にパディング取っておくこともできると思うが、よくわからんので作り直しw 83 // [Setting PNG image metadata doesn't work · Issue #7121 · dotnet/wpf](https://github.com/dotnet/wpf/issues/7121) 84 using var fsin = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); 85 var decoder = new JpegBitmapDecoder(fsin, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); 86 var frame = decoder.Frames[0]; 87 var meta = frame.CreateInPlaceBitmapMetadataWriter(); 88 meta.Title = value; 89 90 if (!meta.TrySave()) 91 { 92 Debug.WriteLine("TrySave:false"); 93 using var fsout = new FileStream(FilePath, FileMode.Open, FileAccess.Write, FileShare.ReadWrite); 94 var encoder = new JpegBitmapEncoder(); 95 foreach (var cloneFrame in decoder.Frames) encoder.Frames.Add(BitmapFrame.Create(cloneFrame)); 96 ((BitmapMetadata)encoder.Frames[0].Metadata).Title = value; 97 encoder.Save(fsout); 98 } 99 } 100}

App

xml

1<Application x:Class="Qt6uox4f1iujybm.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Qt6uox4f1iujybm" ShutdownMode="OnMainWindowClose" StartupUri="MainWindow.xaml"> 2 <Application.Resources> 3 <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 4 <local:ImageConverter x:Key="ImageConverter" /> 5 </Application.Resources> 6</Application>

投稿2023/06/14 11:21

編集2023/06/14 14:52
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TN8001

2023/06/14 11:22

見づらくて申し訳ないです。 2窓あるとツメツメでも1万字ぎりぎりでした。。。 ViewModelにロジック駄々洩れですがショウガナイ^^;
nodoita

2023/06/15 00:59

回答ありがとうございます! BindingとMVVMが難しくて中々理解が難しいですが、勉強頑張ります。 動作確認をしたかったため、VisualStudioで新規作成し ソースをコピペしてビルドしてみましたが、エラーが出て実行できません。 NugetではMVVM追加済みです。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.ClassUsingAttributeInsteadOfInheritanceAnalyzer のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.FieldReferenceForObservablePropertyFieldAnalyzer のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.FieldWithOrphanedDependentObservablePropertyAttributesAnalyzer のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.InvalidClassLevelNotifyDataErrorInfoAttributeAnalyzer のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.InvalidClassLevelNotifyPropertyChangedRecipientsAttributeAnalyzer のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyAttributeWithPropertyTargetDiagnosticSuppressor のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.RelayCommandAttributeWithFieldOrPropertyTargetDiagnosticSuppressor のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.UnsupportedCSharpLanguageVersionAnalyzer のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.INotifyPropertyChangedGenerator のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.ObservableObjectGenerator のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>CSC : warning CS8032: アナライザー CommunityToolkit.Mvvm.SourceGenerators.ObservableRecipientGenerator のインスタンスは C:\Users\test\.nuget\packages\communitytoolkit.mvvm\8.2.0\analyzers\dotnet\roslyn4.3\cs\CommunityToolkit.Mvvm.SourceGenerators.dll (ファイルまたはアセンブリ 'System.Collections.Immutable, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。) から作成できません。 1>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(75,5): error : 1>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(75,5): error : 1>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets(75,5): error : Exception.ToString() 縺悟、ア謨励@縺溘◆繧√€∽セ句、匁枚蟄怜・繧定。ィ遉コ縺ァ縺阪∪縺帙s縲・ 1>プロジェクト "TEST_rc41xvof_wpftmp.csproj" のビルドが終了しました -- 失敗。 VisualStudio2022でMVVM使うために、C#のバージョン?を上げないといけないとみて TEST.csprojに<LangVersion>9.0</LangVersion>を追加してみましたが、ビルド出来ない症状は変わりませんでした。 以下のようなエラーも出ています。 エラー TEST C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets 75 エラー TEST C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets 75 エラー Exception.ToString() 縺悟、ア謨励@縺溘◆繧√€∽セ句、匁枚蟄怜・繧定。ィ遉コ縺ァ縺阪∪縺帙s縲・ HTMLClickMap C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets 75 VisualStudio 2022 Version17.3.4を利用してます。 度々申し訳ありませんが、何か分かりますでしょうか。
TN8001

2023/06/15 01:41

> VisualStudio 2022 Version17.3.4を利用してます。 ちょっと古いようなので、最新(version 17.6.3)にアップデートしていただけますか?
nodoita

2023/06/15 01:43

ありがとうございます!アップデートして再度報告させて頂きます!
nodoita

2023/06/15 02:54

バージョンアップしたらなぜか直りました!ありがとうございました!
TN8001

2023/06/15 02:58

よかったです。 文字数ギリギリなため説明をろくに入れられなかったので、不明点があればお気軽にコメントください^^
nodoita

2023/06/15 07:14

すごく初歩的な質問で大変申し訳ないのですが、 SubWindowに「選択」のボタンを表示し、ボタンを押したタイミングでSubwindowで選択している画像を MainWindowに表示させたい場合はどのようにしたら良いのでしょうか? ViewModelにpublic ObservableCollection<Item> NowItems { get; } = new();を追加し Itemsと同じように増減させたりしようとしましたが、そもそも違うと思いました。 MainWindowのItems/Pathを、NowItems/Pathにしたところで無理でした。 調べたところ以下の方法があるようです。 【C#】WPFで画像表示する2つの方法【初心者向け】 https://shinshin-log.com/csharp-insertimage/ 今選択しているリストの画像Pathが分かれば何とかできそうなのですが、 どうやれば取得できるでしょうか? 度々申し訳ありません。よろしくお願いいたします。
TN8001

2023/06/15 09:51

> SubWindowに「選択」のボタンを表示し、ボタンを押したタイミングでSubwindowで選択している画像をMainWindowに表示させたい場合はどのようにしたら良いのでしょうか? あぁなるほど、Subwindowは選択ダイアログなんですね?(ファイル登録と兼務なのはちょっと違和感?) つまり現在SubWindowはモードレス(ツールウィンドウのようにメインウィンドウと同時に使えるウィンドウ)で、出したまま選択も即時反映になっていますが、 ファイルを開くダイアログのようにモーダル(選択するかキャンセルするかとにかく閉じるまでメインウィンドウを触れない)で出だすんです?(モーダルは個人的に好きじゃないので思い当たりませんでした^^; 「(ListViewで)選んだけどやっぱキャンセルする」とかを考えると、今の方式だとちょっと困りますね。 ViewModelに「public Item SelectedItem { get; set; }」のようなプロパティを作るのがお手軽でしょうかね。 ここ(コメント欄)で説明するのも大変ですし、回答も文字数ギリギリすぎるのでGitHubで見てもらってもいいですか?^^; [TN8001/Qt6uox4f1iujybm](https://github.com/TN8001/Qt6uox4f1iujybm) 緑のボタンを押すとZipで落とせます。 [github download - Google 検索](https://www.google.co.jp/search?q=github+download&lr=lang_ja)
nodoita

2023/06/15 23:57

回答ありがとうございます! SubWindowは選択ダイアログでもあり、色々できる画面なのです。 SubWindowで選択ボタンを押した時のみMainWindowの画像が切り替わるようにしたいと思ってます。 SubWindowのボタンを押した時に、今選択している画像内容をMainWindowに転送とか出来たら良いのですが… 頂いたデータを試してみたのですが、選択等のボタンを押していない時にもMainWindowの画像が切り替わってしまってました。
nodoita

2023/06/16 00:47

勘違いしてました!ありがとうございました!!
TN8001

2023/06/16 01:07 編集

> 選択等のボタンを押していない時にもMainWindowの画像が切り替わってしまってました。 > 勘違いしてました!ありがとうございました!! 実際ダイアログかどうかが不安だったので元のも残した形です。 * SubWindow モードレス・即時反映 * SelectDialog モーダル・[Ok][適用]ボタンを押したとき もしかして「モードレス・[適用]ボタンを押したとき」がよかったですか?^^; まあ組み合わせればいい話ですが、そうなら直すのもやぶさかではありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問