2017-03-01 237 views
2

我试图绑定到下面DataGridStringValue对象的集合。但是每个项目都显示在单独的行中。WPF中的TreeView中的DataGrid

我希望它有一个柱状显示。例如,值565477和65656应该显示在一行中。

enter image description here

XAML:

<TreeView> 
    <TreeViewItem Header="Warnings"> 
     <TreeView ItemsSource="{Binding WarningCategories}"> 
      <TreeView.ItemTemplate> 
       <HierarchicalDataTemplate ItemsSource="{Binding Path=Warnings}"> 
        <TextBlock Text="{Binding Path=Category}" /> 
        <HierarchicalDataTemplate.ItemTemplate> 
         <DataTemplate> 
          <DataGrid ItemsSource="{Binding Fields}" AutoGenerateColumns="True" HeadersVisibility="None"> 
          </DataGrid>         
         </DataTemplate> 
        </HierarchicalDataTemplate.ItemTemplate> 
       </HierarchicalDataTemplate> 
      </TreeView.ItemTemplate> 
     </TreeView> 
    </TreeViewItem> 
</TreeView> 

代码隐藏:

public class ViewModel : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     public ObservableCollection<WarningCategory> WarningCategories { get; set; } 


     public ViewModel() 
     { 
     WarningCategories = new ObservableCollection<WarningCategory>(); 

     ObservableCollection<Warning> warnings = new ObservableCollection<Warning> 
     { 
      new Warning(new StringValue("565477"), new StringValue("65656")), 
      new Warning(new StringValue("767455"), new StringValue("75642")), 
     }; 


     WarningCategories.Add(new WarningCategory("Warning One", warnings)); 



     warnings = new ObservableCollection<Warning> 
     { 
      new Warning(new StringValue("565477"), new StringValue("65656")), 
      new Warning(new StringValue("767455"), new StringValue("75642")), 
     }; 



     WarningCategories.Add(new WarningCategory("Warning Two", warnings)); 
     } 



     [NotifyPropertyChangedInvocator] 
     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
     var handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public class WarningCategory 
    { 
     public string Category { get; set; } 

     private ObservableCollection<Warning> m_warnings; 

     public ObservableCollection<Warning> Warnings 

     { 
     get 
     { 
      return m_warnings ?? (m_warnings = new ObservableCollection<Warning>()); 
     } 
     } 


     public WarningCategory(string category, ObservableCollection<Warning> animals) 

     { 
     Category = category; 

     m_warnings = animals; 
     } 
    } 

    public class Warning 

    { 
     public ObservableCollection<StringValue> Fields { get; set; } 

     public Warning(params StringValue[] fields) 

     { 
     Fields = new ObservableCollection<StringValue>(fields); 
     } 
    } 

    public class StringValue 
    { 
     public StringValue(string s) 
     { 
     Value = s; 
     } 
     public string Value { get; set; } 
    } 

我想最后的结果是这样的:

enter image description here

我的解决方法到目前为止,但遗憾的是它不支持多选!

<ItemsControl ItemsSource="{Binding Fields}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Orientation="Horizontal"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Value}" Width="150"/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
+0

你真的想要在数据网格中有多行吗?为什么你使用数据网格? –

+0

@DanField实际上没有。但我想能够选择整行。我发现DataGrid中的功能 - – Vahid

+0

您可以在文章中添加一些内容,以显示您期望最终输出的样子吗? –

回答

-1

创建一个您将用于数据绑定的新类。

CLASS

Public class MainClass 
{ 
    public void MainClass(string row,string rowValue) 
    { 
     Row = row; 
     RowValue= rowValue; 
    } 
    public string Row 
    { 
    get; 
    set; 
    } 
    public string RowValue 
    { 
    get; 
    set; 
    } 
} 

视图模型

 private ObservableCollection<MainClass> _mainClassList = new ObservableCollection<MainClass>(); 
     public ObservableCollection<MainClass> MainClassList 
     { 
      get { return _mainClassList; } 
      set 
      { 
       _mainClassList= value; 
       NotifyPropertyChanged(m => m.MainClassList); 
      } 
     } 
     public void AddItems() 
     { 
     _mainClassList.Add(new MainClass("row1","row1Value")) 
     _mainClassList.Add(new MainClass("row2","row2Value")) 
     MainClassList = _mainClassList; 
     } 

XAML的

<DataGrid CanUserAddRows="True" RowHeight="23" AutoGenerateColumns="False" ItemsSource="{Binding MainClassList}"> 
       <DataGrid.Columns> 
        <DataGridTextColumn Width="70*" Header="Column1" Binding="{Binding Row,Mode=OneWay}"></DataGridTextColumn> 
        <DataGridTextColumn Width="70*" Header="Column2" Binding="{Binding RowValue,Mode=OneWay}"></DataGridTextColumn> 
       </DataGrid.Columns> 
</DataGrid> 
+0

什么是Column1Value? – Vahid

+0

@Vahid编辑它为你 –

+0

@Vahid它的工作原理和做你想要它做的,为什么downvote? –

1

代替数据网格(其可以枢转,但它是有问题的)使用列表框具有用于ItemsPanel

水平的StackPanel
<DataTemplate> 
    <ListBox ItemsSource="{Binding Fields}"> 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
     <StackPanel Orientation="Horizontal"/> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 

    <ListBox.ItemTemplate> 
     <DataTemplate> 
     <TextBlock Text="{Binding Path=Value}"/> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
    </ListBox>  

    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="IsSelected" 
        Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType=TreeViewItem}}"/> 
     </Style> 
    </ListBox.ItemContainerStyle> 
</DataTemplate> 

,使全行选择我创建ListBoxItem.IsSelected来TreeViewItem.IsSelected

+0

感谢Ash,我希望能够选择整行。 – Vahid

+0

@Vahid,看我的编辑 – ASh

+0

谢谢。它的工作原理,但只有当我点击一个单元格时,整个行才被选中,悬停时只有一个单元格被选中。 – Vahid

0

我建议对一个DataGrid结合,我也想返工你的模板当前正在使用的方式。这样的事情是非常接近你想要什么,我想:

<TreeView> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type local:WarningCategory}" ItemsSource="{Binding Warnings}"> 
      <TextBlock Text="{Binding Path=Category}" /> 
      <HierarchicalDataTemplate.ItemTemplate> 
       <DataTemplate> 
        <ListBox ItemsSource="{Binding}" SelectionMode="Extended"> 
         <TextBlock Text="{Binding FieldsPivoted}" /> 
        </ListBox> 
       </DataTemplate> 
      </HierarchicalDataTemplate.ItemTemplate> 
     </HierarchicalDataTemplate> 
     <!--<DataTemplate DataType="{x:Type local:Warning}"> 
      <TextBlock Text="{Binding FieldsPivoted}" /> 
     </DataTemplate>--> 
    </TreeView.Resources> 

    <TreeViewItem Header="Warnings" ItemsSource="{Binding WarningCategories}" /> 
</TreeView> 

有了这个添加到您的Warning类:

public string FieldsPivoted 
{ 
    get 
    { 
     return string.Join(", ", Fields.Select(x => x.Value)); 
    } 
} 

是这样的:

enter image description here

使用一个列表应该允许您选择多种选择。

+0

丹,我现在使用类似的方法,但不幸的是,这并没有解决我的问题。请看我编辑: – Vahid

+0

编辑 - 它现在有一个列表框,允许多行选择。 –

+0

感谢丹,请你上传图片。我错过了一些东西。我现在可以选择一行。 – Vahid