【问题标题】:WPF Style Combobox with two columns in dropdown下拉菜单中有两列的 WPF 样式组合框
【发布时间】:2012-12-08 09:42:51
【问题描述】:

我环顾四周,发现了一些东西,现在卡在下拉区域中显示两列的组合框上。我有一个可用的 xaml 主题,并且组合框“样式”已定义并且在整个过程中都按预期运行良好,所以这部分没问题。

现在,我有一个组合框,我需要显示两个值,将其视为下拉列表的状态缩写和状态名称,来自项目的 DataTable.DefaultView 绑定源。

如果我有

<my:cboStates TextSearch.TextPath="StateAbbrev">
  <ComboBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal" TextSearch.Text="{Binding Path=StateAbbrev}">
        <TextBlock Text="{Binding Path=StateAbbrev}"/>
        <TextBlock Text="{Binding Path=FullStateName}" Margin="10 0"/>
      </StackPanel>
    </DataTemplate>
  </ComboBox.ItemTemplate>
</my:cboStates>

这行得通。现在,我卡住的方式/位置...现在,我希望在 5 个不同的表单上使用相同的功能,并且所有表单都显示相同的内容,并且如果曾经更改(不是这个,而是其他多列组合框),我不想一直把它直接放在表单的 XAML 文件中。

我希望将其放入主题的资源字典文件中,然后一遍又一遍地重复使用该“样式”。说得通。但是,当我这样做并且绑定到数据表时,我尝试作为 Style 执行的唯一结果是下拉菜单显示

的值
System.Data.DataRowView
System.Data.DataRowView
System.Data.DataRowView
System.Data.DataRowView

而不是实际的 2 列。 这是我在“主题”资源字典中的内容。

<DataTemplate x:Key="myStateComboTemplate" >
  <StackPanel Orientation="Horizontal"  >
    <TextBlock Text="{Binding Path=StateAbbrev}"/>
    <TextBlock Text="{Binding Path=FullStateName}"/>
  </StackPanel>
</DataTemplate>

<Style x:Key="StyleMyStatesCombobox" TargetType="{x:Type ComboBox}" 
  BasedOn="{StaticResource MyOtherWorkingComboBoxStyle}" >
  <Setter Property="TextSearch.TextPath" Value="{Binding Path=StateAbbrev}" />
  <Setter Property="ItemTemplate" Value="{StaticResource myStateComboTemplate}" />
</Style>

所以,如果我在表单上创建了我的“cboStates”类的两个实例,并将一个设置为第一个列出的显式样式,第二个基于“样式”设置,则第二个仅显示重复的System.Data.DataRowView 条目,而不是实际的数据内容。

我错过了什么。

所以,为了澄清我在寻找什么...... 国家...前数据

AL Alabama
AK Alaska
AZ Arizona
AR Arkansas
CA California
CO Colorado
CT Connecticut
DE Delaware

我希望组合框显示缩写 AL、AK、A​​Z 等和更窄的组合框。这也将是返回时的“SelectedValue”。

实际的下拉菜单会显示上面列出的数据,显示缩写和状态的详细描述。

所需组合框的示例

【问题讨论】:

  • 有什么理由不能将两者附加在一起?我在想你总是可以尝试使用元组,但不确定它会如何工作。
  • @Bob,被认为是元组,但这只是一个简单的示例,说明将在任何人都可以理解的组合框中填充什么。实际上,我将拥有各种类似的组合框,它们的数据来自表并且可能会有所不同,因此不是固定值。我不想查询数据库,然后循环并放入另一个存储元组,只是为了根据结果组合框表示的需要重新解析键/值/替代值/额外键等。
  • Dictionary&lt;string, string&gt; 怎么样?将Key 绑定到一个TextBlock 并将Value 绑定到另一个TextBlock?还是有可能多于两行?
  • 您可以发布 MyOtherWorkingComboBoxStyle 资源的标记吗?

标签: c# wpf combobox styles multiple-columns


【解决方案1】:

终于让它工作了......对于那些尝试类似的人。由于我试图拥有一个可以在整个过程中使用的标准“类”实例,但不想在每个页面中显式地硬引用 XAML,因此必须在实际的代码内类实例期间处理部分样式。

由于我不完全知道 .net 框架如何/何时在何处构建其所有控件、样式分配等,因此我很沮丧的是,如果直接从 xaml 中它会起作用,但在代码中会失败。所以,我最终在代码中强制使用了项目模板和 TextSearch.TextPath 值。这是该类的简短sn-p

public class myStatesCombo : ComboBox
{
   public myStatesCombo()
   {
      Loaded += myAfterLoaded;
   }

   protected static DataTable myTableOfStates;

   public void myAfterLoaded()
   {
      if( myTableOfStates == null )
        myTableOfStates = new DataTable();

      CallProcedureToPopulateStates( myTableOfStates );

      ItemsSource = myTableOfStates.DefaultView;

      // AFTER the object is created, and all default styles attempted to be set,
      // FORCE looking for the resource of the "DataTemplate" in the themes.xaml file
      object tryFindObj = TryFindResource("myStateComboTemplate" );
      if( tryFindObj is DataTemplate )
         ItemTemplate = (DataTemplate)tryFindObj;

      // NOW, the CRITICAL component missed in the source code
      TextSearch.SetTextPath( this, "StateAbbrev" );
   }
}

现在,特别注意。在我用来填充数据表的例程中,我预先检查表是否存在。第一次,我创建了表。如果我需要重新填充它,如果我每次都继续做一个“新的 DataTable”,它会吹走数据/项目模板绑定。为了防止这种情况,我会这样做

if( myTableOfStates.Rows.Count > 0 )
  myTableOfStates.Rows.Clear();

那么,我打电话给我的

Sqlexecute 调用从数据库 (DataAdapter) 和 Fill() 数据表中查询。

因此,现在所有内容似乎都已正确填充,显示和文本搜索的绑定已完成并准备就绪。

【讨论】:

    猜你喜欢
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    相关资源
    最近更新 更多