Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我的图像滑块代码的PropertyChanged事件为';他没有被养大_C#_Wpf_Xaml_Mvvm - Fatal编程技术网

C# 我的图像滑块代码的PropertyChanged事件为';他没有被养大

C# 我的图像滑块代码的PropertyChanged事件为';他没有被养大,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我正在尝试用本机WPF控件实现一个图像滑块。单击“下一步”、“上一步”或“添加新属性”时,所选索引和当前图像属性的PropertyChanged事件未触发 视图模型: namespace WpfApplication2.ImageSlider { public class ImageList : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged;

我正在尝试用本机WPF控件实现一个图像滑块。单击“下一步”、“上一步”或“添加新属性”时,所选索引和当前图像属性的
PropertyChanged
事件未触发

视图模型:

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();
        }
    }
}
XAML:


你弄错了。。。。这就是它不起作用的原因 属性已更改不要设置值,只有信号系统才能从属性中获取值

作为新的ImageListClass尝试此选项

`

公共类ImageListFixed:INotifyPropertyChanged
{
#区域字段
私有ObservableCollection图像=新ObservableCollection();
私有int-selectedIndex;
私有图像项当前图像;
#端域字段
#区域属性
公众可观测采集图像
{
获取{返回图像;}
设置{images=value;}
}
公共整数选择索引
{
获取{return selectedIndex;}
设置
{
如果(值-1)
{
selectedIndex=value;OnPropertyChanged();
CurrentImage=图像[selectedIndex];
}
}
}
公共图像项目当前图像
{
获取{return currentImage;}
设置{currentImage=value;OnPropertyChanged();}
}
#端域属性
#区域公共方法
下一个公共空间()
{
选择dex++;
}
公众退票()
{
选择索引--;
}
#端域公共方法
#区域方法
public void AddNewImage()
{
OpenFileDialog dlg=新建OpenFileDialog();
dlg.Filter=“图像文件(*.jpg,*.jpeg,*.jpe,*.gif,*.png,*.bmp,*.tif)|*.jpg;*.jpeg;*.jpe;*.gif;*.png,*.bmp,*.tif”;
dlg.ShowDialog();
如果(dlg.FileName!=“”)
{
Add(newImageItem(){URI=newURI(dlg.FileName)});
SelectedIndex=Images.Count-1;
}
}
#端域法
#区域构造函数
公共ImageListFixed()
{
_canExecute=true;
}
#端域构造函数
#区域命令
专用ICommand_clickCommand;
公共ICommand ClickCommand
{
得到
{
返回_clickCommand??(_clickCommand=newcommandHandler(()=>AddNewImage(),_canExecute));
}
}
私人楼宇可执行;
私有ICommand下一个命令;
公共ICommand下一个命令
{
得到
{
if(nextCommand==null)
{
nextCommand=newcommandhandler(()=>OnNextCommand(),true);
}
返回下一个命令;
}
设置{nextCommand=value;}
}
私有void OnNextCommand()
{
Next();
}
私有ICommand backCommand;
公共ICommand back命令
{
得到
{
if(backCommand==null)
{
backCommand=newcommandhandler(()=>OnBackCommand(),true);
}
返回返回命令;
}
设置{backCommand=value;}
}
私有void OnBackCommand()
{
背();
}
#endregion命令
#区域inotifyproperty已更改
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
#endregion InotifyProperty已更改
}`
删除窗口中的所有后台代码,并将窗口代码更改为以下内容:

<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>

问题在于,按钮使用的
ImageList
对象与图像显示使用的对象不同。您已经在XAML中将
ImageList
的一个新实例声明为
DataContext
对象。您的代码隐藏确实尝试将此对象分配给
\u list
字段,该字段支持您用来调用
Back()
Next()
方法的
list
属性

但是这种分配字段的尝试是错误的代码,甚至不会起作用,因为从来没有人调用属性的setter。因此getter总是返回您在字段初始值设定项中分配的空
ImageList
对象

您应该只提供一个getter并强制转换
DataContext
值:

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

    public ImageList list 
    {
        get { return (ImageList)DataContext; }
    }

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

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

我认为这可能是因为您的DataContext没有设置为包含处理程序的MainWindow实例。您具体说的“不触发”是什么意思?单击第一个按钮时,您发布的代码将调用例如
Back\u Click()
方法,该方法将调用
list.Back()
方法。你发布的代码中没有任何东西可以阻止这一点。但你的问题中没有任何东西表明你可能在问其他问题。在任何情况下,如果您的问题是关于事件的,那么您不需要发布多个按钮或实际图像来重现“不触发”行为。请提供一个很好的例子,并准确地解释问题是什么。@PeterDuniho我在代码中提到了确切的问题发生的地方
PropertyChanged
为null,并且未激发
CurrentImageProperty
。好的,谢谢。你的问题根本不清楚(包括代码中关于
null
值的隐晦注释),但我已经编辑了你的标题和问题,使其现在变得清晰,并提供了问题的答案(我不同意另一个答案,至少就眼前的问题而言).我用的是C版本<6。你能改进一下这个吗<代码>PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName))大多数这只是一个偏好问题,而不是功能问题,用命令绑定取代事件处理,两者都是wor
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();
    }
}
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

}`
<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>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public ImageList list 
    {
        get { return (ImageList)DataContext; }
    }

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

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