Treeview加载和数据绑定的问题 [英] problem with treeview loading and databinding
本文介绍了Treeview加载和数据绑定的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
大家好!这是一个简单的MVVM treeview项目,它显示(应该显示!)Tasks的treeView和一个显示Task内容(例如TaskName)的文本框.问题是根本没有显示树项目!这些是使用的类:
Hey all! This is a simple MVVM treeview project which displays (is supposed to display!) a treeView of Tasks and a textbox showing the Task contents (TaskName for instance). The problem is that the tree items are not shown at all! These are the classes used:
public class TaskTreeViewModel
{
TaskViewModel vmRooT;
List<TaskViewModel> vmFirstGeneration;
public TaskTreeViewModel(Task rootTask)
{
vmRooT = new TaskViewModel(rootTask);
vmFirstGeneration = new List<TaskViewModel>(new TaskViewModel[] { vmRooT });
}
}
class TaskViewModel : INotifyPropertyChanged
{
private Task vmTask;
private List<TaskViewModel> vmSubTasks;
TaskViewModel vmParent;
//Task status
bool vmIsExpanded;
bool vmIsSelected;
#region properties
public string Name
{
get
{return vmTask.TaskName;}
}
public List<TaskViewModel> SubTasks
{
get
{return vmSubTasks;}
}
public TaskViewModel Parent
{
get
{return vmParent;}
}
#endregion
#region ctors
private TaskViewModel(Task task, TaskViewModel parent)
{
vmTask = task;
vmParent = parent;
///<summary>
///recursively walks down the Task tree, wrapping each Task object in a TaskViewModel
///</summary>
vmSubTasks = new List<TaskViewModel>(
(from t in vmTask.SubTasks
select new TaskViewModel(t, this)).ToList<TaskViewModel>());
}
public TaskViewModel(Task task)
: this(task, null)
{ }
#endregion
#region Presentation Members
/// <summary>
/// Gets/sets whether the TreeViewItem
/// associated with this object is expanded.
/// </summary>
public bool IsExpanded
{
get { return vmIsExpanded; }
set
{
if (value != vmIsExpanded)
{
vmIsExpanded = value;
this.OnPropertyChanged("IsExpanded");
}
// Expand all the way up to the root.
if (vmIsExpanded && vmParent != null)
vmParent.vmIsExpanded = true; //fantastic! (executes the setter again)
}
}
/// <summary>
/// Gets/sets whether the TreeViewItem
/// associated with this object is selected.
/// </summary>
public bool IsSelected
{
get { return vmIsSelected; }
set
{
if (value != vmIsSelected)
{
vmIsSelected = value;
this.OnPropertyChanged("IsSelected");
}
}
}
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
public class Task
{
//auto-implemented properites
public string TaskName { get; set; }
public string Description { get; set; }
public List<Task> SubTasks { get; set; }
#region ctors
public Task()
{
TaskName = string.Empty;
Description = string.Empty;
SubTasks = new List<Task>();
}
public Task(string strTaskName)
: this()
{
TaskName = strTaskName;
}
public Task(string strTaskName, string strDescription)
: this(strTaskName)
{
Description = strDescription;
}
public Task(string strTaskName, List<Task> subs)
: this(strTaskName)
{
SubTasks = subs;
}
public Task(string strTaskName, string strDescription, List<Task> subs)
: this(strTaskName, strDescription)
{
SubTasks = subs;
}
public Task(string strTaskName, string strDescription, params string[] strSubTasksNames)
: this(strTaskName, strDescription)
{
SubTasks = new List<Task>();
foreach (var strSub in strSubTasksNames)
{
SubTasks.Add(new Task(strSub));
}
}
#endregion ctors
}
这些是XAML文件及其背后的代码:
And these are the XAML file and its code-behind:
<Window x:Class="Task_it__with_MVVM_.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Task it!" Height="570" Width="850" WindowStartupLocation="CenterScreen">
<Grid FlowDirection="RightToLeft" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TreeView Name="tvTasks" Grid.Column="0" Margin="10" MinHeight="280" ItemsSource="{Binding vmFirstGeneration}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubTasks}">
<TextBlock Text="{Binding Name}" FontSize="14"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<GroupBox Grid.Column="1" Header="details" Margin="10">
<StackPanel Margin="10" DataContext="{Binding ElementName=tvTasks, Path=SelectedItem}" >
<StackPanel Margin="1">
<Label FontSize="14" Margin="1">Name</Label>
<TextBox Name="txtName" Text="{Binding Name}" FontSize="16" Margin="1" Width="auto">
</TextBox>
</StackPanel>
</StackPanel>
</GroupBox>
</Grid>
</Window>
后台代码:
code-behind:
public partial class MainWindow : Window
{
//RootTask which is the fixed permanent Task at the root
public Task RootTask { get; set; }
TaskTreeViewModel vmTaskTree { get; set; }
//ctor
public MainWindow()
{
InitializeComponent();
PrepareTree_Data();
}
public void PrepareTree_Data()
{
// Get raw task tree data
RootTask = SaveLoad.LoadData();//This is method just initializes the RootTask
// Create UI-friendly wrappers around the
// raw data objects (i.e. the view-model).
vmTaskTree = new TaskTreeViewModel(RootTask);
// Let the UI bind to the view-model.
base.DataContext = vmTaskTree;
}
}
推荐答案
解决方法很简单.只需更改所有List< t>改为"ObservableCollection< t>".
问候,
塔里克(Tarik)
Hi,
Solution is very simple. Just change all List<t> to "ObservableCollection<t>.
Regards,
Tarik
这篇关于Treeview加载和数据绑定的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文