我正在尝试通过MVVM学习WPF,但遇到了一个我无法解决的问题。我试图在弹出窗口上显示3个列表,但是我想从MainViewmodel(这些列表在reportviewmodel中)中插入值到这些列表中。事实是,如果我从reportviewmodel的构造函数中添加值,则会显示出来,但如果我想从MainViewModel中添加它们,则不会显示出来。在调试器中,一切正常,但未在U.I上显示谢谢
XAML
<Popup x:Name="Pop" IsOpen="{Binding IsChecked, ElementName=PCheckBox}"
PlacementTarget="{Binding ElementName=PCheckBox}"
AllowsTransparency="True"
PopupAnimation="Slide"
HorizontalOffset="450"
VerticalOffset="-60"
Margin="0,0,8,8"
/>
<Border BorderThickness="1" BorderBrush="Black">
<Grid DataContext="{Binding}" Width="300" Height="300" Background="Gainsboro" Margin="0">
<Grid.RenderTransform>
<RotateTransform x:Name="theTransform" />
</Grid.RenderTransform>
<Button Width="50" Height="50" HorizontalAlignment="Left" Command="{Binding AbortCommand, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" VerticalAlignment="Bottom" Content="Abort"/>
<TreeView>
<TreeView.DataContext>
<vm:ReportViewModel/>
</TreeView.DataContext>
<TreeViewItem Header="Error" IsExpanded="True">
<ListView>
<GridViewColumn DisplayMemberBinding="{Binding Error}"/>
</ListView>
</TreeViewItem>
<TreeViewItem Header="Warning" IsExpanded="True">
<ListView>
<GridViewColumn DisplayMemberBinding="{Binding Warning}"/>
</ListView>
</TreeViewItem>
<TreeViewItem Header="Information" IsExpanded="True">
<ListView>
<GridViewColumn DisplayMemberBinding="{Binding Information}"/>
</ListView>
</TreeViewItem>
</TreeView>
</Grid>
</Border>
</Popup>
MainViewModel
class AdminViewModel : ViewModelBase
{
private RelayCommand generateCommand;
public RelayCommand GenerateCommand{ get { return generateCommand; } }
public AdminViewModel()
{
generateCommand = new RelayCommand(o => { Generate(); });
abortCommand = new RelayCommand(o => { abort(); });
rvm = new ReportViewModel();
}
rvm = new ReportViewModel();
private ReportViewModel rvm;
private async void Generate()
{
prg = new Progress();
Text = "starting";
Step = 15;
if (CadFilePath == string.Empty) //always true
{
rvm.LogError("Warning", "This is a warning");
IsChecked = true; //for the popup to show
}
ReportViewModel
class ReportViewModel : ViewModelBase
{
private List<string> error;
public List<string> Error
{
get { return error; }
set
{
error = value;
OnPropertyChanged("Error");
}
}
private List<string> warning;
public List<string> Warning
{
get { return warning; }
set { warning = value;
OnPropertyChanged("Warning");
}
}
private List<string> information;
public List<string> Information
{
get { return information; }
set { information = value;
OnPropertyChanged("Information");
}
}
public ReportViewModel()
{
error = new List<string>();
warning = new List<string>();
information = new List<string>();
Warning.Add("Warning");
Warning.Add("Warning2");
Error.Add("404");
}
public void LogError(string severity, string err)
{
Warning.Add(err);
Error.Add(err);
Information.Add(err);
}
}
}
答案 0 :(得分:0)
要设置动态绑定,以便集合中的插入或删除会自动更新UI,该集合必须实现INotifyCollectionChanged接口。此接口公开CollectionChanged事件,该事件在基础集合发生更改时应引发。 WPF提供了ObservableCollection<T>
类,它是实现INotifyCollectionChanged
接口的数据集合的内置实现。
如果要绑定集合并添加或删除元素,请使用ObservableCollection<T>
作为容器。它表示一个动态数据收集,当添加,删除或刷新整个列表时,将提供通知。
因此,您只需要替换ViewModel中的集合类型即可:
class ReportViewModel : ViewModelBase
{
private ObservableCollection<string> error;
public ObservableCollection<string> Error
{
get { return error; }
set
{
error = value;
OnPropertyChanged("Error");
}
}
private ObservableCollection<string> warning;
public ObservableCollection<string> Warning
{
get { return warning; }
set { warning = value;
OnPropertyChanged("Warning");
}
}
private ObservableCollection<string> information;
public ObservableCollection<string> Information
{
get { return information; }
set { information = value;
OnPropertyChanged("Information");
}
}
public ReportViewModel()
{
error = new ObservableCollection<string>();
warning = new ObservableCollection<string>();
information = new ObservableCollection<string>();
Warning.Add("Warning");
Warning.Add("Warning2");
Error.Add("404");
}
public void LogError(string severity, string err)
{
Warning.Add(err);
Error.Add(err);
Information.Add(err);
}
}