我的问题是我在Viewmodel中添加了2个类型文件对象(出于测试原因),这是一个observablecollection,但视图不会随着应用程序的启动而更新。 这是Mainview.cs:
public class MainView:ObservableCollection<Files>
{
public MainView()
{
Files x = new Files("picture", "jpg");
Files x1 = new Files("soundfile", "mp3");
Add(x);
Add(x1);
}}
我做错了什么?以及如何避免这个错误?如果我不更改Files类中的属性并且只想在创建新File对象时更新视图,是否真的需要INotifyPropertyChanged?
我上了这堂课:
public class Files:INotifyPropertyChanged
{
private String _fileName;
public String FileName
{
get { return _fileName; }
set { _fileName = value; OnPropertyChanged("FileName"); }
}
private String _dataType;
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public String DataType
{
get { return _dataType; }
set { _dataType = value; OnPropertyChanged("DataType"); }
}
public Files(string filename, string dataType)
{
this._fileName = filename;
this._dataType = dataType;
}
}
这个ViewModel:
public class MainView:ObservableCollection<Files>
{
public MainView()
{
Files x = new Files("picture", "jpg");
Files x1 = new Files("soundfile", "mp3");
Add(x);
Add(x1);
}
}
在xaml中做到了这一点:
<Window x:Class="ClientTestDesign.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:ClientTestDesign"
xmlns:vm="clr-namespace:ClientTestDesign.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
>
<Window.Resources>
<vm:MainView x:Key="View"></vm:MainView>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="75"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Style="{DynamicResource ForwardBackButton}" Content="Back"></Button>
<Button Grid.Column="1" Style="{DynamicResource StopButton}" Content="Pause"></Button>
<Button Grid.Column="2" Style="{DynamicResource ForwardBackButton}" Content="Forward"></Button>
<ListView Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.ColumnSpan="3">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding /FileName, Source={StaticResource View}}"></TextBlock>
<TextBlock Text="{Binding /FileName, Source={StaticResource View}}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
答案 0 :(得分:2)
像这样更改你的代码;
您的“档案”类;这里没有太大的变化。但是看看我实现属性和OnPropertyChanged的方式。
using System.ComponentModel;
namespace WpfApplication1
{
public class File:INotifyPropertyChanged
{
private string _fileName;
private string _dataType;
public string FileName
{
get { return _fileName; }
set
{
_fileName = value;
OnPropertyChanged("FileName");
}
}
public string DataType
{
get { return _dataType; }
set
{
_dataType = value;
OnPropertyChanged("DataType");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
这是您的ViewModel。如您所见,此视图模型与您的视图模型完全不同。这里有一些注释的属性/方法。如果您计划实现某些命令,那么该代码可能很有用。
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
namespace WpfApplication1
{
public class MainWindowViewModel1:INotifyPropertyChanged
{
private ObservableCollection<File> _files;
private File _selectedFile;
//private ICommand _getFiles;
public ObservableCollection<File> Files
{
get { return _files; }
set
{
_files = value;
OnPropertyChanged("Files");
}
}
public File SelectedFile
{
get { return _selectedFile; }
set
{
_selectedFile = value;
OnPropertyChanged("SelectedFile");
}
}
//public ICommand GetFiles
//{
// get { return _getFiles; }
// set
// {
// _getFiles = value;
// }
//}
//public void ChangeFileName(object obj)
//{
// Files[0].FileName = "File_" + new Random().Next().ToString(CultureInfo.InvariantCulture);
//}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public MainWindowViewModel1()
{
Files = new ObservableCollection<File>();
Files.Add(new File() { FileName = "picture", DataType = "jpg"});
Files.Add(new File() { FileName = "soundfile", DataType = "mp3" });
//GetFiles = new RelayCommand(ChangeFileName, param => true);
}
}
}
你的观点;看看绑定。这是你的一个问题。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:vm="clr-namespace:WpfApplication1">
<Window.Resources>
<vm:MainWindowViewModel1 x:Key="View"></vm:MainWindowViewModel1>
</Window.Resources>
<Grid>
<ListView HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Source={StaticResource View}, Path=Files, Mode=TwoWay}" SelectedItem="{Binding Source={StaticResource View}, Path= SelectedFile, Mode=TwoWay}" Margin="28,27,31,146">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path= FileName, Mode=TwoWay}"></TextBlock>
<TextBlock Text="{Binding Path= DataType, Mode=TwoWay}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--<Button Content="Refresh" Command="{Binding Source={StaticResource View},Path = GetFiles}" HorizontalAlignment="Left" Height="33" Margin="347,236,0,0" VerticalAlignment="Top" Width="139"/>-->
</Grid>
答案 1 :(得分:1)
您需要设置ListView的ItemsSource。在这种情况下,它与您的DataContext相同,所以只需执行此操作:
<ListView ItemsSource="{Binding}" ... etc...