Foreach treeview-item我有一个自己的数据网格。 Treeview-items和datagrids由绑定填充。
在文本框中,我获得了对datagrids的选定项的绑定。但是这些文本框上的绑定仅适用于第一个数据网格。每个其他数据网格都不会将selecteditem传输到文本框:
以下是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。我的ViewModel保存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)
{
[...]
}
}
我尝试了一些东西,但最后我不知道如何解决这个问题。有什么问题?我的建议是地方模型中的''SelectedMachine'属性......
这是一个示例项目(使用Sebastian Richter的附加解决方案)。它显示了问题:https://www.file-upload.net/download-12370581/DatagridTreeViewError.zip.html
答案 0 :(得分:1)
我很安静,确保您忘记在班级INotifyPropertyChanged
中实施PlaceModel
。问题是在您更改选择后,将更新属性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
属性并将其添加回ViewModel:
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}" />
通过这个,您的示例项目可以正确更新TextBox。