c# WPF MVVM: изменение размера миниатюр с помощью ползунка - PullRequest
0 голосов
/ 31 марта 2020

Целью моего приложения является отображение всех изображений (* .png, * .jpg ...) каталога в виде миниатюр.
Размер миниатюр следует изменять с помощью ползунка.
Это должно быть MVVM-приложение.

Чтобы упростить мою проблему, я сократил свое приложение до уровня ядра:

  • Grid.Row 0: управление ползунком. TextBlock показывает фактическое значение слайдера. Работает, как и ожидалось.
  • Сетка. Ряд 1: Изображения должны отображаться в виде миниатюр в ListBox.

MainWindow.xaml

       <Window x:Class="WpfApp.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d"
         Title="MainWindow" Height="250" Width="600">

      <Grid>

        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition/>
        </Grid.RowDefinitions>

        <Grid Grid.Row="0" >
          <StackPanel Orientation="Horizontal">
            <TextBlock  Text="Size" Margin="10"></TextBlock>

            <Slider
              Value="{Binding ThumbnailSize}"
              HorizontalAlignment="Left"
              IsSnapToTickEnabled="True"
              Margin="10"
              Maximum="100"
              Minimum="10"
              TickFrequency="5"
              TickPlacement="BottomRight"
              VerticalAlignment="Top"
              Width="400"/>

            <TextBlock  Text="Slider value" Margin="10"></TextBlock>

            <TextBlock Text="{Binding ThumbnailSizeString, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"  Margin="10"></TextBlock>

          </StackPanel>
        </Grid>

        <ListBox 
          ItemsSource="{Binding List_Thumbnail_DM}"      
          ScrollViewer.HorizontalScrollBarVisibility="Disabled"
          Grid.Row="1" 
          Margin="10">

          <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
              <WrapPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
          </ListBox.ItemsPanel>

          <ListBox.ItemTemplate>
            <DataTemplate>

              <Grid 
                MaxWidth="80" Margin="10">


                <Grid.RowDefinitions>
                  <RowDefinition/>
                  <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <Image 
                  Source="{Binding FilePath}" />

                <TextBlock 
                  Text="{Binding FileName}" 
                  HorizontalAlignment="Center" 
                  Grid.Row="1" 
                  Margin="0 5"/>
              </Grid>

            </DataTemplate>
          </ListBox.ItemTemplate>
        </ListBox>

      </Grid>
    </Window>
    ...

MainWindow.xaml.cs ...

    using System.Windows;
    using WpfApp.Model;

    namespace WpfApp
    {

      public partial class MainWindow : Window
      {
         public MainWindow ()
         {
           InitializeComponent();
           this.DataContext = new Thumbnail_VM();
         }
      }
    }
    ...

Класс "Thumbnail_VM: ViewModelBase" прост:

  • ViewModelBase поддерживает материал PropertyChanged.
  • Вся информация об изображении поддерживает список "List_Thumbnail_DM", основанный на классе "Thumbnail_DM"
  • Инициализация "Thumbnail_DM" просто жестко закодирована в Thumbnail_VM ()
  • Также по умолчанию size thumbnail size.
    using System.ComponentModel;

    namespace WpfApp.Model
    {
      public class ViewModelBase : INotifyPropertyChanged
      {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged (string propertyName)
        {
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
      }
    }



    using System;  

    namespace WpfApp.Model  
    { 
        public class Thumbnail_DM
        {
          public Thumbnail_DM (string strFileName, string strPath)
          { 
            FileName = strFileName;
            FilePath = strPath;
          } 

          public string FileName { get; set; }
          public string FilePath { get; set; }
        } 
     }


     using System.Collections.Generic;

     namespace WpfApp.Model
     {
       public class Thumbnail_VM : ViewModelBase
       {
         private  List<Thumbnail_DM> _list_Thumbnail_DM;
         private  double _dThumbnailSize;
         private  string _strThumbnailSizeString;

         public Thumbnail_VM ()
         {
           _list_Thumbnail_DM = new List<Thumbnail_DM>();

           _list_Thumbnail_DM.Add (new Thumbnail_DM ("Thumbnail 1", @"c:\Temp\1.png"));
           _list_Thumbnail_DM.Add (new Thumbnail_DM ("Thumbnail 2", @"c:\Temp\2.png"));

           ThumbnailSize = 50;
         }

         public List<Thumbnail_DM> List_Thumbnail_DM
         {
           get { return _list_Thumbnail_DM; }
           set { _list_Thumbnail_DM = value; }
         }

         public double ThumbnailSize
         {
           get { return _dThumbnailSize; }
           set { _dThumbnailSize = value;
                 OnPropertyChanged("ThumbnailSize");
                 ThumbnailSizeString = ThumbnailSize.ToString(); }
         }

         public string ThumbnailSizeString
         {
           get { return _strThumbnailSizeString; }
           set { _strThumbnailSizeString = value; 
                 OnPropertyChanged("ThumbnailSizeString"); }
         }
       }
    }

...

Мое приложение работает нормально, если:

    Grid  MaxWidth="80" Margin="10"

в DataTemplate

Но, как я уже говорил, я бы хотел изменить размер миниатюры во время выполнения с помощью ползунка.

    Grid MaxWidth="{Binding ThumbnailSize, Mode=TwoWay}" Margin="10"  

Это не работает!

Информация об ошибке: Ошибка пути BindingExpression: свойство 'ThumbnailSize' не найдено в 'объекте' '' Thumbnail_DM '

Конечно, размер эскиза не является частью «Thumbnail_DM» и НЕ ДОЛЖЕН БЫТЬ свойством модели данных миниатюр, потому что размер является свойством ВСЕХ превью.

Какое правильное решение?
Является ли ListBox лучшим элементом управления для эта проблема?
Я думаю, что ListBox.ItemTemplate является проблемой.
Как его нужно изменить?

...