2010-06-24 44 views
1

我有一個listview,我已經綁定(twoWay)到一個數據表。綁定工作正常,數據在列表視圖中正常顯示。現在我想實現的有點複雜,我甚至不確定這是可以實現的還是現在。DataBinding到列表視圖

我的數據表有15列,我在lisview中顯示5列。如果用戶在列表視圖上選擇一行,可能會在棧面板中的文本塊中顯示該選定行的其他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(); 
    } 

} 

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

=====================

最後的工作代碼

我能做到這一點的幫助下Phil提供的答案。在下面發佈我的更新代碼,因爲它可能對其他人有用。

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

回答

1

下面是一個基本descripti您可以通過一種方式實現這一點。這不是一個理想的解決方案,但應該讓你走上正軌。

  1. 在您的Tables類中創建一個表示數據表中單個行的字段變量。
  2. 在您的Tables類中創建一個方法,將該字段變量設置爲表格中相應的行。
  3. 創建公開該行值的屬性。
  4. 步驟#2的方法需要爲步驟#3(OnPropertyChanged)中公開的所有屬性更改通知。
  5. 在您的代碼後面處理selection_changed事件,並從該事件處理函數調用設置選定行的Tables類中的方法。
  6. 將您的文本塊綁定到步驟#3中公開的 屬性。
+0

感謝菲爾,它工作得很好。我將在我原來的帖子中粘貼更新的代碼。這可能對別人有幫助。 – 2010-06-24 15:13:20

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>