在一列中使用不同类型的控件的未绑定网格

在一列中使用不同类型的控件的未绑定网格

问题描述:

我正在寻找能够在同一列中显示不同控件(现在的文本框和组合框)的WinForms或WPF网格。它还必须具有treelist/treeview功能,以便行(节点)之间的层次结构可见。我需要能够在运行时将控件添加到单元格,并以编程方式更改行高和列宽。
到目前为止,我一直在寻找一段时间,但没有运气。有什么建议么?非常感谢帮助。在一列中使用不同类型的控件的未绑定网格

如果为这样的组件付钱是一种选择,我会强烈推荐Telerik组件。他们有很多控制,技术支持很棒。

你可以看看一些例子来看看他们的产品满足您的需求:

Telerik GridView for WPF

Telerik TreeListView for WPF

+0

马蒂亚斯感谢您的回复速度快,这是一个选择,我会检查出来:) –

这个答案的结果。

enter image description here

我会用标准WPF的DataGrid,没有必要付钱,只是还没有,你可以选择一个模板列,只是做一个小数据里面绑定,下面的例子中有一个非常简单的我绑定到网格的类。

public class ListItemType 
{ 
    public int Type { get; set; } 
    public string Text { get; set; } 
} 

这个类可以明显是什么,但在本例中我设置类型为1或2,在绑定列表中的任何对象,该对象的类型为1中给出的按钮来表示它和任何与一个Type = 2被赋予一个CheckBox来表示它。

datagrid的XAML看起来像这样。 (压痕++)

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" Height="200" HorizontalAlignment="Left" Margin="10,10,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="200" > 
    <DataGrid.Columns> 

     <!-- The template coloumn --> 
     <DataGridTemplateColumn> 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 

        <!-- Each cell is put in to a content presenter so I can change it's content --> 
        <ContentPresenter> 
         <ContentPresenter.Content> 
          <Binding Path="Type"> 
           <Binding.Converter> 
            <local:SwitchConverter> 

             <local:SwitchConverterCase When="1"> 
              <Button Content="{Binding Text}"></Button> 
             </local:SwitchConverterCase> 

             <local:SwitchConverterCase When="2"> 
              <CheckBox Content="{Binding Text}" /> 
             </local:SwitchConverterCase> 


            </local:SwitchConverter> 
           </Binding.Converter> 
          </Binding> 
         </ContentPresenter.Content> 
        </ContentPresenter> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 

上面使用的开关转换器只是一个通用的转换器,它简化了XAML代码一点,你可以使用任何你想要的转换器,但这里是我反正用的一个代码。

/// <summary> 
/// A converter that accepts <see cref="SwitchConverterCase"/>s and converts them to the 
/// Then property of the case. 
/// </summary> 
[ContentProperty("Cases")] 
public class SwitchConverter : IValueConverter 
{ 
    // Converter instances. 
    List<SwitchConverterCase> _cases; 

    #region Public Properties. 
    /// <summary> 
    /// Gets or sets an array of <see cref="SwitchConverterCase"/>s that this converter can use to produde values from. 
    /// </summary> 
    public List<SwitchConverterCase> Cases { get { return _cases; } set { _cases = value; } } 
    #endregion 
    #region Construction. 
    /// <summary> 
    /// Initializes a new instance of the <see cref="SwitchConverter"/> class. 
    /// </summary> 
    public SwitchConverter() 
    { 
     // Create the cases array. 
     _cases = new List<SwitchConverterCase>(); 
    } 
    #endregion 

    /// <summary> 
    /// Converts a value. 
    /// </summary> 
    /// <param name="value">The value produced by the binding source.</param> 
    /// <param name="targetType">The type of the binding target property.</param> 
    /// <param name="parameter">The converter parameter to use.</param> 
    /// <param name="culture">The culture to use in the converter.</param> 
    /// <returns> 
    /// A converted value. If the method returns null, the valid null value is used. 
    /// </returns> 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     // This will be the results of the operation. 
     object results = null; 

     // I'm only willing to convert SwitchConverterCases in this converter and no nulls! 
     if (value == null) throw new ArgumentNullException("value"); 

     // I need to find out if the case that matches this value actually exists in this converters cases collection. 
     if (_cases != null && _cases.Count > 0) 
      for (int i = 0; i < _cases.Count; i++) 
      { 
       // Get a reference to this case. 
       SwitchConverterCase targetCase = _cases[i]; 

       // Check to see if the value is the cases When parameter. 
       if (value == targetCase || value.ToString().ToUpper() == targetCase.When.ToString().ToUpper()) 
       { 
        // We've got what we want, the results can now be set to the Then property 
        // of the case we're on. 
        results = targetCase.Then; 

        // All done, get out of the loop. 
        break; 
       } 
      } 

     // return the results. 
     return results; 
    } 

    /// <summary> 
    /// Converts a value. 
    /// </summary> 
    /// <param name="value">The value that is produced by the binding target.</param> 
    /// <param name="targetType">The type to convert to.</param> 
    /// <param name="parameter">The converter parameter to use.</param> 
    /// <param name="culture">The culture to use in the converter.</param> 
    /// <returns> 
    /// A converted value. If the method returns null, the valid null value is used. 
    /// </returns> 
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

/// <summary> 
/// Represents a case for a switch converter. 
/// </summary> 
[ContentProperty("Then")] 
public class SwitchConverterCase 
{ 
    // case instances. 
    string _when; 
    object _then; 

    #region Public Properties. 
    /// <summary> 
    /// Gets or sets the condition of the case. 
    /// </summary> 
    public string When { get { return _when; } set { _when = value; } } 
    /// <summary> 
    /// Gets or sets the results of this case when run through a <see cref="SwitchConverter"/> 
    /// </summary> 
    public object Then { get { return _then; } set { _then = value; } } 
    #endregion 
    #region Construction. 
    /// <summary> 
    /// Switches the converter. 
    /// </summary> 
    public SwitchConverterCase() 
    { 
    } 
    /// <summary> 
    /// Initializes a new instance of the <see cref="SwitchConverterCase"/> class. 
    /// </summary> 
    /// <param name="when">The condition of the case.</param> 
    /// <param name="then">The results of this case when run through a <see cref="SwitchConverter"/>.</param> 
    public SwitchConverterCase(string when, object then) 
    { 
     // Hook up the instances. 
     this._then = then; 
     this._when = when; 
    } 
    #endregion 

    /// <summary> 
    /// Returns a <see cref="System.String"/> that represents this instance. 
    /// </summary> 
    /// <returns> 
    /// A <see cref="System.String"/> that represents this instance. 
    /// </returns> 
    public override string ToString() 
    { 
     return string.Format("When={0}; Then={1}", When.ToString(), Then.ToString()); 
    } 
} 

最后,对于您需要的树状视图组件..实际上你可以放甚至另一个数据网格的每个单元内实现自己需要的任何深度的层次。

+0

这看起来有我正在寻找的所有东西。我会尽快检查一下,谢谢! –

我想你会发现,一个标准的WPF的TreeView有一些聪明的模板就可以了

+0

我也会看看这个,谢谢:) –