我的图像滑块代码的 PropertyChanged 事件未引发 [英] PropertyChanged event of my Image Slider code isn't being raised

查看:26
本文介绍了我的图像滑块代码的 PropertyChanged 事件未引发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用本机 WPF 控件实现图像滑块.当我单击 Next 或 Back 或 Add a new 时,SelectedIndexCurrentImage 属性的 PropertyChanged 事件不会触发.

I am trying to implement an image slider with native WPF controls. The PropertyChanged events for the SelectedIndex and CurrentImage properties aren't firing when I click Next or Back or Add a new one.

视图模型:

namespace WpfApplication2.ImageSlider
{
    public class ImageList : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private ObservableCollection<ImageItem> _Images = new ObservableCollection<ImageItem>();

        public ObservableCollection<ImageItem> Images
        {
            get
            { return _Images; }
        }

        private int _SelectedIndex;


        public static readonly PropertyChangedEventArgs SelectedIndexProperty = new PropertyChangedEventArgs("SelectedIndex");

        public int SelectedIndex
        {
            get { return _SelectedIndex; }
            set
            {
                _SelectedIndex = value;

                var handler = PropertyChanged;  // value is null
                if (handler != null)
                {
                    handler(this, SelectedIndexProperty);
                    handler(this, CurrentImageProperty);
                }
            }
        }


        public static readonly PropertyChangedEventArgs CurrentImageProperty = new PropertyChangedEventArgs("CurrentImage");   //Not Firing


        private ImageItem _CurrentImage;

        public ImageItem CurrentImage      //Not Firing
        {
            get { return _CurrentImage; }
            set
            {
                _CurrentImage = value;

                if (Images.Count > 0)
                {
                    CurrentImage =
                    Images[SelectedIndex];
                }

            }
        }

        public void Next()
        {
            if (SelectedIndex < Images.Count - 1)
                SelectedIndex++;
            else
                SelectedIndex = 0;
        }
        public void Back()
        {
            if (SelectedIndex == 0)
                SelectedIndex = Images.Count - 1;
            else
                SelectedIndex--;
        }

        private ICommand _clickCommand;
        public ICommand ClickCommand
        {
            get
            {
                return _clickCommand ?? (_clickCommand = new CommandHandler(() => AddNewImage(), _canExecute));
            }
        }
        public ImageList()
    {
        _canExecute = true;
    }
        private bool _canExecute;

        public void AddNewImage()
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.gif, *.png, *.bmp, *.tif) | *.jpg; *.jpeg; *.jpe; *.gif; *.png, *.bmp, *.tif";
            dlg.ShowDialog();

            if (dlg.FileName != "")
            {
                Images.Add(new ImageItem() { URI = new Uri(dlg.FileName) });

                var handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, CurrentImageProperty);
                }
            }
        }
    }

    public class CommandHandler : ICommand
    {
        private Action _action;
        private bool _canExecute;
        public CommandHandler(Action action, bool canExecute)
        {
            _action = action;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _action();
        }
    }
}

型号:

namespace WpfApplication2.ImageSlider
{
    public class ImageItem
    {
        public Uri URI { get; set; }

        private BitmapSource _Source;

        public BitmapSource Source
        {
            get
            {
                try
                {
                    if (_Source == null) _Source = new BitmapImage(URI);//lazy loading

                }
                catch (Exception)
                {
                    _Source = null;
                }
                return _Source;
            }
        }

        public void Save(string filename)
        {
            var img = BitmapFrame.Create(Source);
            var encoder = new JpegBitmapEncoder();

            encoder.Frames.Add(img);
            using (var saveStream = System.IO.File.OpenWrite(filename))
                encoder.Save(saveStream);

        }


    }

}

XAML:

<Window x:Class="WpfApplication2.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"
         xmlns:local="clr-namespace:WpfApplication2.ImageSlider"
        mc:Ignorable ="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BitmapImage x:Key="NotFound" UriSource="E:\..\NotFound.png"/>
    </Window.Resources>
    <Window.DataContext>
        <local:ImageList/>
    </Window.DataContext>
    <DockPanel>
        <Button Content="&lt;" Click="Back_Click"/>
        <Button DockPanel.Dock="Right" Content="&gt;" Click="Next_Click"/>
        <Image Source="{Binding CurrentImage.Source, Mode=OneWay,
               TargetNullValue={StaticResource NotFound},
               FallbackValue={StaticResource NotFound}}"/>
        <Button Content="Add" Command="{Binding ClickCommand}"></Button>
    </DockPanel>
</Window>

XAML.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private ImageList _list= new ImageList();

    public ImageList list 
    {
        get { return _list; }
        set { _list = DataContext as ImageList; }  //The count of the images is always 0;
    }

    private void Next_Click(object sender, RoutedEventArgs e)
    {
        list.Next();
    }

    private void Back_Click(object sender, RoutedEventArgs e)
    {
        list.Back();
    }
}

推荐答案

你弄错了......这就是它不起作用的原因属性已更改请勿设置值,它只会向系统发出信号以从属性中获取值.

You have made it wrong.... that's why it's not working Property changed DO NOT set value it only signal system to GET value from property.

试试这个作为新的 ImageListClass

try this as new ImageListClass

`

public class ImageListFixed : INotifyPropertyChanged
    {
        #region Fields
    private ObservableCollection<ImageItem> images = new ObservableCollection<ImageItem>();
    private int selectedIndex;
    private ImageItem currentImage;

    #endregion Fields

    #region Properties

    public ObservableCollection<ImageItem> Images
    {
        get { return images; }
        set { images = value; }
    }

    public int SelectedIndex
    {
        get { return selectedIndex; }
        set
        {
            if(value < Images.Count && value > -1)
            {
                selectedIndex = value; OnPropertyChanged();
                CurrentImage = Images[selectedIndex];
            }
        }
    }

    public ImageItem CurrentImage
    {
        get { return currentImage; }
        set { currentImage = value; OnPropertyChanged(); }
    }

    #endregion Properties

    #region Public Methods

    public void Next()
    {
        SelectedIndex ++;
    }

    public void Back()
    {
        SelectedIndex--;
    }

    #endregion Public Methods

    #region Methods

    public void AddNewImage()
    {
        OpenFileDialog dlg = new OpenFileDialog();
        dlg.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.gif, *.png, *.bmp, *.tif) | *.jpg; *.jpeg; *.jpe; *.gif; *.png, *.bmp, *.tif";
        dlg.ShowDialog();

        if(dlg.FileName != "")
        {
            Images.Add(new ImageItem() { URI = new Uri(dlg.FileName) });
            SelectedIndex = Images.Count - 1;
        }
    }

    #endregion Methods

    #region Constructors

    public ImageListFixed()
    {
        _canExecute = true;
    }

    #endregion Constructors

    #region Commands

    private ICommand _clickCommand;
    public ICommand ClickCommand
    {
        get
        {
            return _clickCommand ?? (_clickCommand = new CommandHandler(() => AddNewImage(), _canExecute));
        }
    }

    private bool _canExecute;

    private ICommand nextCommand;

    public ICommand NextCommand
    {
        get
        {
            if (nextCommand == null)
            {
                nextCommand = new CommandHandler(()=> OnNextCommand(), true);
            }
            return nextCommand;
        }
        set { nextCommand = value; }
    }

    private void OnNextCommand()
    {
        Next();
    }
    private ICommand backCommand;

    public ICommand BackCommand
    {
        get
        {
            if(backCommand == null)
            {
                backCommand = new CommandHandler(() => OnBackCommand(), true);
            }
            return backCommand;
        }
        set { backCommand = value; }
    }

    private void OnBackCommand()
    {
        Back();
    }

    #endregion Commands




    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion INotifyPropertyChanged

}`

删除窗口中的所有返回代码并将窗口代码更改为如下所示:

Delete all back code at you window and change window code to something like this:

<DockPanel>
    <Button Content="&lt;" Command="{Binding BackCommand}"/>
    <Button DockPanel.Dock="Right" Content="&gt;" Command="{Binding NextCommand}"/>
    <Image Source="{Binding CurrentImage.Source, Mode=OneWay}"/>
    <Button Content="Add" Command="{Binding ClickCommand}"></Button>
</DockPanel>

这篇关于我的图像滑块代码的 PropertyChanged 事件未引发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆