お世話になります。
色々と試しているのですが、分からないため教えてください。
実現したいこと
【1】WPF 動的生成したRectangleがドラッグで移動できない、Bindingが難しい…
https://teratail.com/questions/j700zzpncph60k
【2】WPF C# ImageSourceを利用しているからか、画像がロックされてしまう
https://teratail.com/questions/t6uox4f1iujybm
上記2つのものを組み合わせて作成途中です。
・プロパティ 'SelectedRect' が型 'DataGrid' に見つかりませんでした。
というエラーが気になる
・ObservableCollection<PicInfo> PicInfoCollection
で、ListViewで今選択している値を抽出してSelectPicに入れたり
今選択している値を削除したりしたい
前提
MainWindowでRectangleを生成したり操作したりします。
SubWindowでは、SubWindowで選択した画像を最背面に表示します。
選択した画像とRectangleを組み合わせ、ファイルを作成する予定です。
そのため、Rectangleの値(X,Y,Width,Height,色、位置など)
選択した画像の値(画像メタデータのタイトル、画像タイトル、画像ファイルパス、その他紐づくいろんな値)が必要になってきます。
再利用するために、取り回し良く?する必要があります。
とりあえず今はシンプルに
RectangleのX,Y画像のファイルパス、画像ファイル名、タイトル…など必要最低限のデータに絞って作成してます。
発生している問題・エラーメッセージ
プロパティ 'SelectedRect' が型 'DataGrid' に見つかりませんでした。
実行は問題なくできるのですが、上記のように表示されることがあり気になってます。
また、SelectPicには値が入っているのにMainWindowに画像が表示されません。
該当のソースコード
MainWindow
1 <Window.Resources> 2 <x:Array x:Key="Colors" Type="sys:String"> 3 <sys:String>transparent</sys:String> 4 <sys:String>red</sys:String> 5 <sys:String>blue</sys:String> 6 </x:Array> 7 </Window.Resources> 8 <Grid> 9 <Grid.RowDefinitions> 10 <RowDefinition Height="30" /> 11 <RowDefinition Height="600"/> 12 <RowDefinition Height="*"/> 13 </Grid.RowDefinitions> 14 <ToolBar Grid.Row="0" VerticalAlignment="Top" Height="30"> 15 <Button Content="画像選択" Width="128" Height="32" Click="Button_Click"/> 16 <RadioButton x:Name="DefaultButton" Width="32" Height="32" 17 Content="↖" IsChecked="True" /> 18 <RadioButton x:Name="RectButton" Width="32" Height="32"> 19 <Rectangle Width="24" Height="16" Stroke="Black"/> 20 </RadioButton> 21 </ToolBar> 22 23 <Image Source="{Binding SelectedPic.PicFilePath}" StretchDirection="DownOnly" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1" ></Image> 24 <local:MyCanvas MinHeight="600" MaxHeight="600" Height="600" MinWidth="800" Width="800" MaxWidth="800" Grid.Row="1" 25 Items="{Binding RectInfoCollection}" 26 SelectedRect="{Binding ElementName=datagrid,Path=SelectedRect, Mode=TwoWay}" /> 27 28 <DataGrid Name="datagrid" 29 Grid.Row="2" 30 ItemsSource="{Binding RectInfoCollection}" SelectionMode="Single"> 31 <DataGrid.Columns> 32 <DataGridTextColumn Header="Name" MinWidth="50" Binding="{Binding Name}" /> 33 <DataGridTextColumn Header="X" Binding="{Binding X}" /> 34 <DataGridTextColumn Header="Y" Binding="{Binding Y}" /> 35 </DataGrid.Columns> 36 </DataGrid> 37 </Grid>
SubWindow
1 <DockPanel> 2 <StatusBar DockPanel.Dock="Bottom"> 3 <StatusBarItem> 4 <TextBlock Text="{Binding PicInfoCollection/PicFilePath}" /> 5 </StatusBarItem> 6 </StatusBar> 7 8 <Grid> 9 <Grid.ColumnDefinitions> 10 <ColumnDefinition /> 11 <ColumnDefinition Width="5" /> 12 <ColumnDefinition Width="2*" /> 13 </Grid.ColumnDefinitions> 14 <Grid.RowDefinitions> 15 <RowDefinition Height="*"/> 16 <RowDefinition Height="50"/> 17 </Grid.RowDefinitions> 18 19 <ListView IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding PicInfoCollection}"> 20 <ListView.View> 21 <GridView> 22 <GridViewColumn Width="200" Header="タイトル"> 23 <GridViewColumn.CellTemplate> 24 <DataTemplate> 25 <TextBox Width="200" Padding="1" Text="{Binding PicTitle}" TextWrapping="Wrap" /> 26 </DataTemplate> 27 </GridViewColumn.CellTemplate> 28 </GridViewColumn> 29 <GridViewColumn DisplayMemberBinding="{Binding PicName}" Header="ファイル名" /> 30 <GridViewColumn> 31 <GridViewColumn.CellTemplate> 32 <DataTemplate> 33 <Button Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" CommandParameter="{Binding}" Content="削除" /> 34 </DataTemplate> 35 </GridViewColumn.CellTemplate> 36 </GridViewColumn> 37 </GridView> 38 </ListView.View> 39 </ListView> 40 41 <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" /> 42 43 <ListView Grid.Column="2" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding PicInfoCollection}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"> 44 <ListView.ItemsPanel> 45 <ItemsPanelTemplate> 46 <WrapPanel /> 47 </ItemsPanelTemplate> 48 </ListView.ItemsPanel> 49 <ListView.ItemTemplate> 50 <DataTemplate> 51 <Grid Width="150" Height="150"> 52 <TextBlock Text="{Binding PicTitle}" /> 53 <Image Source="{Binding PicFilePath, Converter={StaticResource ImageConverter}}" /> 54 </Grid> 55 </DataTemplate> 56 </ListView.ItemTemplate> 57 </ListView> 58 <StackPanel Grid.Row="1" Grid.Column="2" Orientation="Horizontal"> 59 <Button x:Name="MainPicShow" Margin="5" Padding="10" Content="メインウィンドウに表示" 60 Click="Ok_Button_Click" Command="{Binding ApplyCommand}" CommandParameter="{Binding PicInfoCollection/}"/> 61 <Button x:Name="DeleteButton" Margin="5" Padding="10" Content="削除"/> 62 </StackPanel> 63 </Grid> 64 </DockPanel>
ViewModel
1public class ViewModel : BindableBase 2{ 3 private ObservableCollection<RectInfo> _rectInfoCollection = null!; 4 public ObservableCollection<RectInfo> RectInfoCollection { get => _rectInfoCollection; set => SetProperty(ref _rectInfoCollection, value); } 5 6 private ObservableCollection<PicInfo> _picInfoCollection = null!; 7 public ObservableCollection<PicInfo> PicInfoCollection { get => _picInfoCollection; set => SetProperty(ref _picInfoCollection, value); } 8 public PicInfo? SelectedPic { get; set; } 9 private readonly string ImageFolder; 10 private readonly string HtmlFolder; 11 12 public ViewModel() 13 { 14 RectInfoCollection = MyData.RectInfos; 15 PicInfoCollection = MyData.PicInfos; 16 ImageFolder = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "image"); 17 if (!Directory.Exists(ImageFolder)){ 18 Directory.CreateDirectory(ImageFolder); 19 } 20 HtmlFolder = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "html"); 21 if (!Directory.Exists(HtmlFolder)) 22 { 23 Directory.CreateDirectory(HtmlFolder); 24 } 25 ImportFiles(Directory.EnumerateFiles(ImageFolder, "*.jpg", SearchOption.TopDirectoryOnly)); 26 } 27 28 public void ImportFiles(IEnumerable<string> paths) 29 { 30 foreach (var path in paths) PicInfoCollection.Add(new(path)); 31 } 32 33 public void AddItem(string path, Func<bool> isOverwrite) 34 { 35 var fileName = System.IO.Path.GetFileNameWithoutExtension(path); 36 var outPath = System.IO.Path.Combine(ImageFolder, $"{fileName}.jpg"); 37 38 if (File.Exists(outPath)) 39 { 40 if (!isOverwrite()) return; 41 PicInfoCollection.Remove(PicInfoCollection.FirstOrDefault(x => x.PicFilePath == outPath)!); 42 } 43 44 using (var fsin = new FileStream(path, FileMode.Open, FileAccess.ReadWrite)) 45 using (var fsout = new FileStream(outPath, FileMode.Create, FileAccess.Write)) 46 { 47 var f = BitmapFrame.Create(fsin, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand); 48 var meta = f.Metadata.Clone() as BitmapMetadata ?? new BitmapMetadata("jpg"); 49 var enc = new JpegBitmapEncoder(); 50 enc.Frames.Add(BitmapFrame.Create(f, f.Thumbnail, meta, f.ColorContexts)); 51 enc.Save(fsout); 52 } 53 54 PicInfoCollection.Add(new(outPath)); 55 }
試したこと
PicInfoCollectionを作りました。
SubWindowを開き、無事画像が表示されるようになりましたが
MainWindowに表示されません。
また、画像の削除等も出来ないです。
PicInfoCollectionから、今操作しているものの逆探知?みたいなのが出来て
それをSelectPicに入れたり、PicInfoCollectionから削除できたりしたら
分かりやすくて良いのですが、
DelegateCommand.csと同じ(Class名とかのみ変更)のClassファイルを
作成し、ボタンクリック時に動作させようともしましたが、
それも上手くいきませんでした。
SubWindow.xaml.cs
1 private void Ok_Button_Click(object sender, RoutedEventArgs e) 2 { 3 if (MyList.SelectedItem == null) 4 { 5 DialogResult = true; // ListViewで何も選択されていない場合は何もしない 6 } 7 else 8 { 9 PicInfo item = (PicInfo)MyList.SelectedItem; // ListViewで選択されている項目を取り出す 10 viewModel.SelectedPic = item; 11 DialogResult = true; 12 } 13 }
MainWindow.xaml
1 <Image Source="{Binding SelectedPic.PicFilePath}" StretchDirection="DownOnly" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1" ></Image>
上記のようにしても、画像はMainWindowに表示されません。
SelectedPicに値は入ったようなのですが…。
補足情報(FW/ツールのバージョンなど)
Visualstudio2022 V17.6.3
.NET 6.0 C#
0 コメント