2009-12-28 63 views
3

我有一个显示TFS查询结果的列表框。我想在后面的代码中更改ListBoxItem的样式,以使查询结果中包含的列。WPF - 在代码后面更改代码样式

ListBoxItem的样式在Windows.Resoruces节中定义。我试过这个:

public T GetQueryResultsElement<T>(string name) where T : DependencyObject 
{ 
    ListBoxItem myListBoxItem = 
     (ListBoxItem)(lstQueryResults.ItemContainerGenerator.ContainerFromIndex(0)); 

    // Getting the ContentPresenter of myListBoxItem 
    ContentPresenter myContentPresenter = 
     myListBoxItem.Template.LoadContent().FindVisualChild<ContentPresenter>(); 

    // Finding textBlock from the DataTemplate that is set on that ContentPresenter 
    DataTemplate myDataTemplate = myContentPresenter.ContentTemplate; <------+ 
    T myControl = (T)myDataTemplate.FindName(name, myContentPresenter);  | 
                       |  
    return (T)myControl;              | 
}                    | 
                       | 
     ContentTemplate is null ----------------------------------------------+ 

但是ContentTemplate为null。我从here获得了该代码,然后使用LoadContent调用(原始代码为ContentPresenter提供了空值)对其进行了修改。

无论如何。如果你知道一种方法来改变背后代码中的现有风格,我很乐意看到它。


具体细节,如果你希望他们:
我在我的一个ListBoxItem风格去为WrapPanel。这是我想要添加额外的TextBlock项目。

这里是我的风格部分:

<!--Checkbox ListBox--> 
<Style x:Key="CheckBoxListStyle" TargetType="ListBox"> 
    <Style.Resources> 
     <Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem"> 
      <Setter Property="Tag" Value="{Binding Id}"/> 
      <Setter Property="Background"> 
       <Setter.Value> 
        <Binding Path="Type" Converter="{StaticResource WorkItemTypeToColorConverter}" /> 
       </Setter.Value> 
      </Setter> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="ListBoxItem"> 
         <Border BorderThickness="1" BorderBrush="#D4D4FF"> 
          <Grid Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WrapPanel}}, Path=ActualWidth}" ScrollViewer.CanContentScroll="True" Margin="2"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="20" /> 
            <ColumnDefinition Width="*" /> 
            <ColumnDefinition Width="30" /> 
           </Grid.ColumnDefinitions> 
           <Grid.Background> 
            <Binding Path="Type" Converter="{StaticResource WorkItemTypeToColorConverter}" /> 
           </Grid.Background> 

           <CheckBox VerticalAlignment="Center" Grid.Column="0" IsChecked="{Binding IsSelected, 
             RelativeSource={RelativeSource TemplatedParent}, 
             Mode=TwoWay}" Name="chkIsSelected" /> 
           <WrapPanel Grid.Column="1" Margin="5,0,5,0" Name="QueryColumns"> 
            <TextBlock VerticalAlignment="Center" Text="{Binding Id}" Name="txtID" /> 
            <TextBlock VerticalAlignment="Center" Margin="5,0,5,0" Text="{Binding Title}" Name="txtTitle" /> 
           </WrapPanel> 

回答

11

你要对粮食这里,试图直接在代码隐藏操作的视觉元素。有一个涉及数据绑定的简单解决方案。

我将提供一般解决方案,因为我不知道解决方案的具体情况。

一旦得到查询结果,就创建一个枚举,该枚举返回列名和每次迭代的字段值。

例子:

class NameValuePair 
{ 
    public string Name { get; set; } 
    public object Value { get; set; } 
} 

public IEnumerable<IEnumerable<NameValuePair>> EnumerateResultSet(DataTable resultSet) 
{ 
    foreach (DataRow row in resultSet.Rows) 
     yield return EnumerateColumns(resultSet, row); 
} 

public IEnumerable<NameValuePair> EnumerateColumns(DataTable resultSet, DataRow row) 
{ 
    foreach (DataColumn column in resultSet.Columns) 
     yield return new NameValuePair 
      { Name = column.ColumnName, Value = row[column] }; 
} 

而在你的后台代码,一旦你得到你的数据表的结果集,这样做:

myResultsList.ItemsSource = EnumerateResultSet(myDataTable); 

的XAML可能是这样的:

<Window.Resources> 
    <DataTemplate x:Key="ColumnTemplate"> 
     <Border BorderBrush="Black" BorderThickness="1" CornerRadius="2" Padding="2"> 
      <WrapPanel> 
       <TextBlock Text="{Binding Name}" Margin="0,0,5,0"/> 
       <TextBlock Text="{Binding Value}" Margin="0,0,10,0"/> 
      </WrapPanel> 
     </Border> 
    </DataTemplate> 
    <DataTemplate x:Key="RowTemplate"> 
     <Grid> 
      <ItemsControl 
       ItemsSource="{Binding}" 
       ItemTemplate="{StaticResource ColumnTemplate}" 
       Margin="0,5,0,5"/> 
     </Grid> 
    </DataTemplate> 
</Window.Resources> 
<Grid> 
    <ListBox Name="myResultsList" ItemTemplate="{StaticResource RowTemplate}"/> 
</Grid> 

样品输出:

Sample Output Image

+1

这很好用!更何况,这是一个梦幻般的答案。我已经将它设置为答案,但由于堆栈溢出问题,我无法对它作出回应。我已经提交它作为一个错误元:http://meta.stackexchange.com/questions/34009/cant-upvote-an-answer-says-the-vote-it-too-old非常感谢你采取有时间帮助我解决这个问题。当你以正确的方式进行WPF时,WPF是非常棒的,但是当你走错了路时,WPF会很好。谢谢你给我展示的路径... – Vaccano 2009-12-28 21:55:30

+0

你对你最后的声明是非常正确的:) 不客气! – 2009-12-28 21:57:10