2017-03-01 56 views
0

Foreach treeview-item我有一個自己的數據網格。 Treeview-items和datagrids是通過綁定來填充的。如何獲取多個數據網格的SelectedItem?

在文本框上我綁定了選定的數據網格項。但是對這些文本框的綁定僅適用於第一個數據網格。每隔數據網格並在將selectedItem不會轉移到文本框:

wrong binding

這裏是與DataGrid樹視圖:

  <TreeView ItemsSource="{Binding Path=PlaceList}"> 
       <TreeView.ItemTemplate> 
        <DataTemplate> 
         <TreeViewItem Header="{Binding Path=Name}"> 
          <DataGrid ItemsSource="{Binding MachinesInPlace, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
             SelectionUnit="FullRow" 
             SelectedItem="{Binding SelectedMachine, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
             AutoGenerateColumns="True" 
             IsSynchronizedWithCurrentItem="True" 
             SelectionMode="Single"> 
          </DataGrid> 
         </TreeViewItem> 
        </DataTemplate> 
       </TreeView.ItemTemplate> 
      </TreeView> 

這裏是文本框:

<TextBox Text="{Binding PlaceList/SelectedMachine.Name, ValidatesOnDataErrors=True}" /> 

我我正在與MvvmLight合作。我的視圖模型持有PlaceList:

public ObservableCollection<PlaceModel> PlaceList { get; set; } = new ObservableCollection<PlaceModel>(); 

    public ObjectInspectorViewModel() 
    { 
     PlaceList = PlaceModel.GetPlaces(BaseResourcePaths.PlacesCsv); 
    } 

這是我的地方的模型:

public class PlaceModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } = "_CurrentObjectName"; 
    public string Length { get; set; } 
    public string Width { get; set; } 
    public string Height { get; set; } 
    public ObservableCollection<MachineModel> MachinesInPlace { get; set; } 
    public MachineModel SelectedMachine { get; set; } 

    public static ObservableCollection<PlaceModel> GetPlaces(string filepath) 
    { 
     [...] 
    } 
} 

我想出來的東西,但最後我不知道如何解決的bug。有什麼問題?我的建議是位置模型內的屬性'SelectedMachine'...

這是一個示例項目(帶有Sebastian Richter的附加解決方案)。它顯示了以下問題:https://www.file-upload.net/download-12370581/DatagridTreeViewError.zip.html

+0

難道你不需要樹視圖上的SelectedItem,然後根據它做你的綁定到文本框?否則,綁定僅抓取第一個實例,並且在進行樹視圖選擇時不會更新。 – Josh

+0

Thx for your reply。我試過你的解決方案,但它沒有奏效。我不得不用http://stackoverflow.com/a/3535089上的SelectedItem屬性來擴展treeview控件。我結束了以下XAML:http://pastebin.com/VVgBtCqR問題是樹視圖擁有一個充滿地方的列表,並且在每個地方是一個不同的(datagrid)機器列表。所以在treeview-選擇我可以得到哪個地點列表被選中,但我不能得到那些地方列表中選擇哪臺機器。或者我錯了? – Chpo7234

回答

1

我很安靜,確定您忘記在您的課程PlaceModel中實施INotifyPropertyChanged。問題在於您更改了選擇後,屬性Placemodel.SelectedMachine將會更新,但不會觸發任何事件來在視圖中填充此更改。

因爲您使用MVVM Light,您可以從已經實現此接口的ObservableObject派生。 因此改變你的PlaceModel到下面的代碼:

public class PlaceModel : ObservableObject 
{ 
    private MachineModel _selectedMachine; 
    public int Id { get; set; } 
    public string Name { get; set; } = "_CurrentObjectName"; 
    public string Length { get; set; } 
    public string Width { get; set; } 
    public string Height { get; set; } 
    public ObservableCollection<MachineModel> MachinesInPlace { get; set; } 

    public MachineModel SelectedMachine 
    { 
     get 
     { 
      return _selectedMachine; 
     } 

     set 
     { 
      // raises Event PropertyChanged after setting value 
      Set(ref _selectedMachine, value); 
     } 
    } 

    public static ObservableCollection<PlaceModel> GetPlaces(string filepath) 
    { 
    [...] 
} 

編輯:

我想結合不知道從您的ObservableCollection(多對一關係)綁定到該元素,因爲你把它作爲您的TextBox中的參考。

因此,嘗試從模型中刪除SelectedMachine財產並將其重新添加到視圖模型:

class ViewModel : ViewModelBase 
{ 
    ... 
    private MachineModel _selectedMachine; 
    public MachineModel SelectedMachine 
    { 
     get 
     { 
      return _selectedMachine; 
     } 
     set 
     { 
     // raises Event PropertyChanged after setting value 
     Set(ref _selectedMachine, value); 
     } 
    } 
    ... 
} 

而且改變你的XAML到下面的代碼(我用實例項目):

<Grid x:Name="LayoutRoot"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="2*"></RowDefinition> 
     <RowDefinition></RowDefinition> 
    </Grid.RowDefinitions> 

    <!-- Row #1 --> 
    <Grid> 
     <!-- TreeView und DataGrids--> 
     <TreeView ItemsSource="{Binding Path=PlaceList}"> 
      <TreeView.ItemTemplate> 
       <DataTemplate> 
        <TreeViewItem Header="{Binding Path=Name}"> 
         <DataGrid ItemsSource="{Binding MachinesInPlace, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
            SelectedItem="{Binding DataContext.SelectedMachine, RelativeSource={RelativeSource AncestorType=Window},Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
        </TreeViewItem> 
       </DataTemplate> 
      </TreeView.ItemTemplate> 
     </TreeView> 
    </Grid> 

    <!-- Row #2 --> 
    <Grid Grid.Row="1"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition></ColumnDefinition> 
      <ColumnDefinition Width="2*"></ColumnDefinition> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition></RowDefinition> 
      <RowDefinition></RowDefinition> 
     </Grid.RowDefinitions> 

     <Label Grid.Row="0" 
       Content="ID" /> 
     <!-- Textboxen aktualisieren nur bei Auswahl der ersten Datagrid --> 
     <TextBox Grid.Column="2" 
       Grid.Row="0" 
       Text="{Binding SelectedMachine.Id, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
     <Label Grid.Row="1" 
       Content="Name" /> 
     <TextBox Grid.Column="2" 
       Grid.Row="1" 
       Text="{Binding SelectedMachine.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
    </Grid> 
</Grid> 

關鍵是爲SelectedItem設置正確的DataContext。爲此,我使用以下XAML代碼:

<DataGrid ItemsSource="{Binding MachinesInPlace, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
            SelectedItem="{Binding DataContext.SelectedMachine, RelativeSource={RelativeSource AncestorType=Window},Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 

使用此示例項目可正確更新TextBoxes。

+0

謝謝你的幫助。事實上,我忘了'INotifyPropertyChanged'接口/'ObservableObject'。我將這個想法添加到我的代碼中,但它沒有解決問題。在我的問題中,我添加了一個更精確地顯示問題的項目示例。我認爲'SelectedMachine'必須在'PlaceModel'之外。但是如果我把屬性'PlaceList'和'SelectedMachine'放到我的viewmodel中,我無法訪問我的xaml-datagrid中的'SelectedMachine',因爲我在上面的treeview中設置了一個'PlaceList':http://pastebin.com/ 20HwpPga – Chpo7234

+0

請參閱我的編輯。 –

+0

我非常感謝你的努力!有問題的Visual Studio不會在綁定窗口中顯示屬性'DataContext.SelectedMachine',所以我需要手動設置它。見[這張照片](https://picload.org/image/rlcgogwr/binding2.png)。如果沒有你的幫助,我永遠不會發現這一點,非常感謝你! – Chpo7234