C# WPF将列表返回给类
对于VB web表单中的WPF和C#来说是个新手,所以对于这个结构糟糕的问题我很抱歉,我将根据需要补充以改进。我试图通过向MySQL添加数据库调用来实现一个示例,以填充随需应变树视图控件。这里是到示例代码的链接 数据库连接正常,数据正在填充数据集。我迭代以将其放入列表中。但似乎无法解决将列表传递给类以填充控件的问题C# WPF将列表返回给类,c#,wpf,C#,Wpf,对于VB web表单中的WPF和C#来说是个新手,所以对于这个结构糟糕的问题我很抱歉,我将根据需要补充以改进。我试图通过向MySQL添加数据库调用来实现一个示例,以填充随需应变树视图控件。这里是到示例代码的链接 数据库连接正常,数据正在填充数据集。我迭代以将其放入列表中。但似乎无法解决将列表传递给类以填充控件的问题 public class Level1 { public Level1(string level1Name) { this.Level1Name =
public class Level1
{
public Level1(string level1Name)
{
this.Level1Name = level1Name;
}
public string Level1Name { get; private set; }
readonly List<Level2> _level2s = new List<Level2>();
public List<Level2> Level2s
{
get { return _level2s; }
}
}
试试下面这个
List L1=新列表();
foreach(级别1s中的var行)
{
Level1 L=新的Level1();
//L.Level1Name=row.ToString();此处根据需要添加项目
L1.加入(L);
}
返回L1.ToArray();
试试下面这个
List L1=新列表();
foreach(级别1s中的var行)
{
Level1 L=新的Level1();
//L.Level1Name=row.ToString();此处根据需要添加项目
L1.加入(L);
}
返回L1.ToArray();
试试下面这个
List L1=新列表();
foreach(级别1s中的var行)
{
Level1 L=新的Level1();
//L.Level1Name=row.ToString();此处根据需要添加项目
L1.加入(L);
}
返回L1.ToArray();
试试下面这个
List L1=新列表();
foreach(级别1s中的var行)
{
Level1 L=新的Level1();
//L.Level1Name=row.ToString();此处根据需要添加项目
L1.加入(L);
}
返回L1.ToArray();
您应该使用MVVM设计模式来解决这个问题。您的问题中列出的要求不多,因此我将假设我自己的要求,这将引导您走上正确的道路 首先要确定的是,在呈现
TreeView
之前,您的记录在运行时是否准备就绪/被提取,以及它们是否会在应用程序的生命周期中从结构中更改/更新/添加/删除。如果不改变结构,您可以继续使用List
作为收藏。如果您(或用户)将要从集合中添加/删除,并最终更改结构,则需要通知UI集合发生了更改;因此,您可以使用内置的。这里是一个MVVM纯粹主义解决方案,假设您的数据将在应用程序启动时提取,并且您将修改集合:
注意:RelayCommand
的实现取自
模型
视图模型 模型提供者 MainWindow.xaml
您应该使用MVVM设计模式来解决这个问题。您的问题中列出的要求不多,因此我将假设我自己的要求,这将引导您走上正确的道路 首先要确定的是,在呈现
TreeView
之前,您的记录在运行时是否准备就绪/被提取,以及它们是否会在应用程序的生命周期中从结构中更改/更新/添加/删除。如果不改变结构,您可以继续使用List
作为收藏。如果您(或用户)将要从集合中添加/删除,并最终更改结构,则需要通知UI集合发生了更改;因此,您可以使用内置的。这里是一个MVVM纯粹主义解决方案,假设您的数据将在应用程序启动时提取,并且您将修改集合:
注意:RelayCommand
的实现取自
模型
视图模型 模型提供者 MainWindow.xaml
您应该使用MVVM设计模式来解决这个问题。您的问题中列出的要求不多,因此我将假设我自己的要求,这将引导您走上正确的道路 首先要确定的是,在呈现
TreeView
之前,您的记录在运行时是否准备就绪/被提取,以及它们是否会在应用程序的生命周期中从结构中更改/更新/添加/删除。如果不改变结构,您可以继续使用List
作为收藏。如果您(或用户)将要从集合中添加/删除,并最终更改结构,则需要通知UI集合发生了更改;因此,您可以使用内置的。这里是一个MVVM纯粹主义解决方案,假设您的数据将在应用程序启动时提取,并且您将修改集合:
注意:RelayCommand
的实现取自
模型
视图模型 模型提供者 MainWindow.xaml
您应该使用MVVM设计模式来解决这个问题。您的问题中列出的要求不多,因此我将假设我自己的要求,这将引导您走上正确的道路 第一件事是确定你的记录是否正确
List<string> level1s = new List<string>();
DataSet ds = new DataSet();
foreach (DataTable table in ds.Tables)
{
foreach (DataRow row in table.Rows)
{
level1s.Add((string)row["name"]);
}
}
**UPDATE**: Trying to return the list...
return new Level1[]
{
foreach(DataRow row in level1s)
{
// iterate here
}
};
using BusinessLib;
namespace TreeViewWithViewModelTOC.LoadOnDemand
{
public class Level1ViewModel : TreeViewItemViewModel
{
readonly Level1 _level1;
public Level1ViewModel(Level1 level1)
: base(null, true)
{
_level1 = level1;
}
public string Level1Name
{
get { return _level1.Level1Name; }
}
protected override void LoadChildren()
{
foreach (Level2 level2 in Database.GetLevel2s(_level1))
base.Children.Add(new Level2ViewModel(level2, this));
}
}
}
List<Level1> L1=new List<Level1>();
foreach(var row in level1s)
{
Level1 L=new Level1();
// L.Level1Name = row.ToString(); here add items as you need
L1.Add(L);
}
return L1.ToArray();
public class First
{
public string Name
{
get;
set;
}
public readonly List<Second> Children;
public First(string name)
{
Name = name;
Children = new List<Second>
{
new Second(1),
new Second(2),
new Second(3),
};
}
public void AddChild(Second child)
{
Children.Add(child);
ChildAdded(this, new ChildAddedEventArgs(child));
}
public EventHandler<ChildAddedEventArgs> ChildAdded;
}
public class ChildAddedEventArgs //technically, not considered a model
{
public readonly Second ChildAdded;
public ChildAddedEventArgs(Second childAdded)
{
ChildAdded = childAdded;
}
}
public class Second
{
public int Number
{
get;
set;
}
public Second(int number)
{
Number = number;
}
}
public class MainViewModel : INotifyPropertyChanged
{
private readonly ObservableCollection<FirstViewModel> _items;
private readonly ICommand _addFirstFirstChildCommand;
private readonly ICommand _addSecondFirstChildCommand;
private readonly ICommand _toggleExpandCollapseCommand;
private bool _firstAddedFlag;
public MainViewModel(IEnumerable<First> records)
{
_items = new ObservableCollection<FirstViewModel>();
foreach(var r in records)
{
_items.Add(new FirstViewModel(r));
}
_addFirstFirstChildCommand = new RelayCommand(param => AddFirst(), param => CanAddFirst);
_addSecondFirstChildCommand = new RelayCommand(param => AddSecond(), param => CanAddSecond);
_toggleExpandCollapseCommand = new RelayCommand(param => ExpandCollapseAll(), param =>
{
return true;
});
}
public ObservableCollection<FirstViewModel> Items
{
get
{
return _items;
}
}
public ICommand AddFirstFirstChildCommand
{
get
{
return _addFirstFirstChildCommand;
}
}
public ICommand AddSecondFirstChildCommand
{
get
{
return _addSecondFirstChildCommand;
}
}
public ICommand ToggleExpandCollapseCommand
{
get
{
return _toggleExpandCollapseCommand;
}
}
public bool CanAddFirst
{
get
{
return true;
}
}
public bool CanAddSecond
{
get
{
//Only allow second to be added if we added to first, first
return _firstAddedFlag;
}
}
public void AddFirstChild(FirstViewModel item)
{
Items.Add(item);
}
private void AddFirst()
{
_items[0].AddChild(new Second(10));
_firstAddedFlag = true;
}
private void AddSecond()
{
_items[1].AddChild(new Second(20));
}
private void ExpandCollapseAll()
{
foreach(var i in Items)
{
i.IsExpanded = !i.IsExpanded;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class FirstViewModel : INotifyPropertyChanged
{
private readonly First model;
private readonly ObservableCollection<SecondViewModel> _children;
private bool _isExpanded;
public FirstViewModel(First first)
{
_children = new ObservableCollection<SecondViewModel>();
model = first;
foreach(var s in first.Children)
{
Children.Add(new SecondViewModel(s));
}
model.ChildAdded += OnChildAdded;
}
public string FirstName
{
get
{
return model.Name;
}
set
{
model.Name = value;
NotifyPropertyChanged();
}
}
public ObservableCollection<SecondViewModel> Children
{
get
{
return _children;
}
}
public bool IsExpanded
{
get
{
return _isExpanded;
}
set
{
_isExpanded = value;
NotifyPropertyChanged();
}
}
internal void AddChild(Second second)
{
model.AddChild(second);
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void OnChildAdded(object sender, ChildAddedEventArgs args)
{
if(Children != null)
{
Children.Add(new SecondViewModel(args.ChildAdded));
}
}
}
public class SecondViewModel : INotifyPropertyChanged
{
private readonly Second model;
private bool _isExpanded;
public SecondViewModel(Second second)
{
model = second;
}
public int SecondNumber
{
get
{
return model.Number;
}
set
{
model.Number = value;
NotifyPropertyChanged();
}
}
//Added property to avoid warnings in output window
public bool IsExpanded
{
get
{
return _isExpanded;
}
set
{
_isExpanded = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Database
{
public static IEnumerable<First> GetChildren()
{
List<First> firsts = new List<First>();
firsts.Add(new First("John"));
firsts.Add(new First("Roxanne"));
return firsts;
}
}
public partial class MainWindow : Window
{
private MainViewModel mvm;
public MainWindow()
{
var db = Database.GetChildren();
mvm = new MainViewModel(db);
InitializeComponent();
DataContext = mvm;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Do not do this, example only
var f = new First("Billy");
mvm.AddFirstChild(new FirstViewModel(f));
//Prove that the event was raised in First, FirstViewModel see & handles it, and
//the UI is updated
f.AddChild(new Second(int.MaxValue));
}
}
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
Title="MainWindow">
<Grid>
<TreeView ItemsSource="{Binding Items}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:FirstViewModel}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding FirstName}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:SecondViewModel}">
<TextBlock Text="{Binding SecondNumber}" />
</DataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded"
Value="{Binding IsExpanded, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
<StackPanel Orientation="Vertical"
VerticalAlignment="Bottom">
<StackPanel Orientation="Horizontal">
<Button Content="Add Child to first First"
Command="{Binding AddFirstFirstChildCommand}" />
<Button Content="Toggle Expand"
Command="{Binding ToggleExpandCollapseCommand}" />
<Button Content="Add Child to second First"
Command="{Binding AddSecondFirstChildCommand}" />
</StackPanel>
<Button Content="Bad Codebehind Button"
Click="Button_Click"/>
</StackPanel>
</Grid>
</Window>
public void Level1[] GetLevels()
{
DataSet ds = ....
return ds.Tables[0].Rows
.Select(row => new Level1((string)row["name"]))
.ToArray();
}
public void Level1[] GetLevels()
{
DataSet ds = ....
return ds.Tables
.SelectMany(t => t.Rows)
.Select(row => new Level1((string)row["name"]))
.ToArray();
}