我有一个listview,我已经绑定(twoWay)到数据表。绑定工作正常,数据在listview上正确显示。现在我想要实现的有点复杂,我甚至不确定这是否可以实现或现在。
我的数据表已经说了15列,我在lisview中显示了5列。如果用户在listview上选择一行,我可以在stackpanel中的textblocks中显示该选定行(来自数据表)的其他10个值。这是可以实现还是我要求太高?我试图通过从问题here获取想法来实现这一目标,但却无法做到这一点。 如果它是可以实现的,你们能告诉我如何继续这个想法吗?
我认为这可以通过处理listview1_selectionChanged事件并手动填充文本框来实现,但是当我处于学习阶段时,我想探索是否可以通过数据绑定来完成。通过这种方式,我将了解各种做事方式,并可以在此过程中构建我的概念。
我在下面附上我的代码。这只是一个测试项目,其中一个列表视图有一列。
XAML:
<Window.Resources>
<Prefs:Tables x:Key="TClass"></Prefs:Tables>
</Window.Resources>
<Grid>
<StackPanel Orientation="Horizontal">
<ListView Name="listView1" Background="Transparent" Height="534" BorderThickness="0 0 0 1" VerticalAlignment="Top">
<ListView.ItemsSource>
<Binding Source="{StaticResource TClass}" Path="Instance.dtAccounts" Mode="TwoWay"></Binding>
</ListView.ItemsSource>
<ListView.View>
<GridView x:Name="GridView1" ColumnHeaderContainerStyle="{StaticResource GridViewHeader}" AllowsColumnReorder="True">
<GridViewColumn Header="Company Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock x:Name="txbName" Padding="0 0 5 0" >
<TextBlock.Text>
<Binding Path="NAME">
</Binding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<StackPanel Name="stkPanel1" Margin="100 0 0 0">
<TextBlock></TextBlock>
</StackPanel>
</StackPanel>
</Grid>
Window1.xaml.cs
public partial class Window1 : Window
{
DataTable dt = new DataTable();
public Window1()
{
InitializeComponent();
Tables.Instance.dtAccounts = Worker.LoadAccounts();
}
}
Class Tables.cs
public class Tables : INotifyPropertyChanged
{
private static Tables instance;
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private DataTable _dtAccounts;
public Tables()
{
}
// Singleton instance read-only property
public static Tables Instance
{
get
{
if (instance == null)
{
instance = new Tables();
}
return instance;
}
}
public DataTable dtAccounts
{
get
{
return _dtAccounts;
}
set
{
_dtAccounts = value;
OnPropertyChanged("dtAccounts");
}
}
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
=====================
最终工作代码
我能够在菲尔提供的答案的帮助下做到这一点。在下面发布我的更新代码,因为它可能对其他人有用。
XAML:
<Grid>
<StackPanel Orientation="Horizontal">
<ListView Name="listView1" Background="Transparent" Height="534" BorderThickness="0 0 0 1" VerticalAlignment="Top" SelectionChanged="listView1_SelectionChanged">
<ListView.ItemsSource>
<Binding Source="{StaticResource TClass}" Path="Instance.dtAccounts" Mode="TwoWay"></Binding>
</ListView.ItemsSource>
<ListView.View>
<GridView x:Name="GridView1" ColumnHeaderContainerStyle="{StaticResource GridViewHeader}" AllowsColumnReorder="True">
<GridViewColumn Header="Company Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Name="txbName" Padding="0 0 5 0" >
<TextBlock.Text>
<Binding Path="NAME">
</Binding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<StackPanel Name="stkPanel1" Margin="100 0 0 0">
<TextBlock>
<TextBlock.Text>
<Binding Source="{StaticResource TClass}" Path="Instance.SelectedName" Mode="TwoWay">
</Binding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</StackPanel>
</Grid>
Window1.xaml.cs
public partial class Window1 : Window
{
DataTable dt = new DataTable();
public Window1()
{
InitializeComponent();
Tables.Instance.dtAccounts = Worker.LoadAccounts();
}
private void listView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListView lstView = sender as ListView;
int item = lstView.SelectedIndex;
Tables.Instance.SetSelectedRow(item);
}
}
Tables.cs
public class Tables : INotifyPropertyChanged
{
private static Tables instance;
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private DataTable _dtAccounts;
private string _selectedName;
public Tables()
{
}
// Singleton instance read-only property
public static Tables Instance
{
get
{
if (instance == null)
{
instance = new Tables();
}
return instance;
}
}
public DataTable dtAccounts
{
get
{
return _dtAccounts;
}
set
{
_dtAccounts = value;
OnPropertyChanged("dtAccounts");
}
}
public string SelectedName
{
get
{
return _selectedName;
}
set
{
_selectedName = value;
OnPropertyChanged("SelectedName");
}
}
public void SetSelectedRow(int index)
{
int indexNo = index;
SelectedName = dtAccounts.Rows[index][0].ToString();
}
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
答案 0 :(得分:1)
以下是您可以实现此目标的基本描述。这不是一个理想的解决方案,但应该让你走上正确的轨道。
答案 1 :(得分:1)
这是类似的事情:
public partial class DynamicListViewWindow : Window
{
public DynamicListViewWindow()
{
InitializeComponent();
ObservableCollection<Person> personList = new ObservableCollection<Person>();
personList.Add(new Person() { FirstName = "John", LastName = "Doe", Age = 30, Address = "123 Doe Street", Phone = "111-111-1111" });
personList.Add(new Person() { FirstName = "Jane", LastName = "Doe", Age = 28, Address = "123 Doe Street", Phone = "222-222-2222" });
personList.Add(new Person() { FirstName = "Mark", LastName = "Doe", Age = 15, Address = "123 Doe Street", Phone = "333-333-3333" });
personList.Add(new Person() { FirstName = "John", LastName = "Smith", Age = 40, Address = "123 Doe Street", Phone = "444-444-4444" });
personList.Add(new Person() { FirstName = "Rosy", LastName = "Smith", Age = 36, Address = "123 Doe Street", Phone = "555-555-5555" });
PersonListView.ItemsSource = personList;
}
private void PersonListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (PersonListView.SelectedIndex >= 0)
{
Object data = PersonListView.SelectedItem;
PropertyInfo[] properties = data.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
ExtraPropertiesPanel.Children.Clear();
foreach (PropertyInfo prop in properties)
{
TextBox tb = new TextBox();
Binding b = new Binding() { Source = data, Path = new PropertyPath(prop.Name) };
tb.SetBinding(TextBox.TextProperty, b);
ExtraPropertiesPanel.Children.Add(tb);
}
}
}
}
public class Person
{
public String FirstName { get; set; }
public String LastName { get; set; }
public Int32 Age { get; set; }
public String Address { get; set; }
public String Phone { get; set; }
}
XAML
<Window x:Class="WPFApplication1.DynamicListViewWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window"
Height="300"
Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0">
<ListView Name="PersonListView" SelectionChanged="PersonListView_SelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name"
DisplayMemberBinding="{Binding FirstName}" />
<GridViewColumn Header="Last Name"
DisplayMemberBinding="{Binding LastName}" />
</GridView>
</ListView.View>
</ListView>
</Border>
<Border Grid.Column="1">
<StackPanel Name="ExtraPropertiesPanel"></StackPanel>
</Border>
</Grid>