Wpf 数据绑定到Listview

Wpf 数据绑定到Listview,wpf,data-binding,listview,Wpf,Data Binding,Listview,我有一个listview,它已绑定(双向)到一个datatable。绑定工作正常,数据在listview上正常显示。现在我想要实现的有点复杂,我甚至不确定这是否可以实现,或者现在 我的datatable有15列,我在lisview中显示了5列。如果用户在listview上选择一行,我可能会在stackpanel的textblocks中显示所选行(来自datatable)的其他10个值。这是可以实现的还是我要求太高了?我试图通过从问题中获取想法来实现这一点,但未能实现。 如果这是可以实现的,你们能

我有一个listview,它已绑定(双向)到一个datatable。绑定工作正常,数据在listview上正常显示。现在我想要实现的有点复杂,我甚至不确定这是否可以实现,或者现在

我的datatable有15列,我在lisview中显示了5列。如果用户在listview上选择一行,我可能会在stackpanel的textblocks中显示所选行(来自datatable)的其他10个值。这是可以实现的还是我要求太高了?我试图通过从问题中获取想法来实现这一点,但未能实现。 如果这是可以实现的,你们能给我一些关于如何进行的想法吗

我认为这可以通过处理listview1_selectionChanged事件并手动填充文本框来实现,但由于我正处于学习阶段,我想探索是否可以通过数据绑定来实现。通过这种方式,我将了解各种做事方式,并在此过程中建立我的概念

我在下面附上我的代码。这只是一个测试项目,一个listview有一个列

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>
<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>
表格.cs

public partial class Window1 : Window
{
    DataTable dt = new DataTable();
    public Window1()
    {
        InitializeComponent();
        Tables.Instance.dtAccounts = Worker.LoadAccounts();
    }

}
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));
        }
    } 
}
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);
    }
}
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));
        }
    } 
}
=====================

最终工作代码

在菲尔提供的答案的帮助下,我做到了这一点。在下面发布我的更新代码,因为它可能对其他人有用

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>
<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>
表格.cs

public partial class Window1 : Window
{
    DataTable dt = new DataTable();
    public Window1()
    {
        InitializeComponent();
        Tables.Instance.dtAccounts = Worker.LoadAccounts();
    }

}
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));
        }
    } 
}
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);
    }
}
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));
        }
    } 
}

以下是实现此目标的基本方法描述。这不是一个理想的解决方案,但应该会让您走上正确的轨道

  • 在Tables类中创建一个字段变量,该变量表示datatable中的一行
  • 在Tables类中创建一个方法,将该字段变量设置为表中的正确行
  • 创建公开行的值的属性
  • 步骤#2的方法需要对步骤#3(OnPropertyChanged)中公开的所有属性执行更改通知
  • 在代码隐藏中处理selection_changed事件,并从该事件处理程序调用Tables类中设置所选行的方法
  • 将文本块绑定到 步骤#3中公开的属性

  • 这里是这样的:

    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; }
    }
    
    public分部类DynamicListViewWindow:Window
    {
    公共DynamicClistViewWindow()
    {
    初始化组件();
    ObservableCollection personList=新的ObservableCollection();
    添加(newperson(){FirstName=“John”,LastName=“Doe”,Age=30,Address=“123 Doe Street”,Phone=“111-111-1111”});
    添加(newperson(){FirstName=“Jane”,LastName=“Doe”,Age=28,Address=“123 Doe Street”,Phone=“222-222-2222”});
    添加(newperson(){FirstName=“Mark”,LastName=“Doe”,Age=15,Address=“123 Doe Street”,Phone=“333-333-3333”});
    添加(newperson(){FirstName=“John”,LastName=“Smith”,年龄=40,地址=“123 Doe Street”,电话=“444-444-4444”});
    添加(newperson(){FirstName=“Rosy”,LastName=“Smith”,Age=36,Address=“123 Doe Street”,Phone=“555-555-5555”});
    PersonListView.ItemsSource=personList;
    }
    private void PersonListView\u SelectionChanged(对象发送者,SelectionChangedEventArgs e)
    {
    如果(PersonListView.SelectedIndex>=0)
    {
    对象数据=PersonListView.SelectedItem;
    PropertyInfo[]properties=data.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
    ExtraPropertiesPanel.Children.Clear();
    foreach(PropertyInfo属性中的属性)
    {
    TextBox tb=新的TextBox();
    Binding b=newbinding(){Source=data,Path=newpropertypath(prop.Name)};
    tb.SetBinding(TextBox.TextProperty,b);
    资产外资产负债表。儿童。新增(tb);
    }
    }
    }
    }
    公共阶层人士
    {
    公共字符串名{get;set;}
    公共字符串LastName{get;set;}
    公共Int32年龄{get;set;}
    公共字符串地址{get;set;}
    公用字符串电话{get;set;}
    }
    
    XAML

    
    

    谢谢,菲尔,它工作得非常好。我会将更新后的代码粘贴到我原来的帖子中。这可能对其他人有帮助。