お世話になります。
色々なところで調べたものを利用させて頂いておりますが、分からないため教えてください。
実現したいこと
- 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を利用してます。
度々申し訳ありませんが、何か分かりますでしょうか。
回答2件
あなたの回答
tips
プレビュー