繁体   English   中英

WPF - 改变代码背后的样式

[英]WPF - Change a style in code behind

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

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。 我从这里获得了代码,然后使用LoadContent调用对其进行了修改(原始代码为ContentPresenter提供了null)。

无论如何。 如果你知道改变代码中现有样式的方法,我很乐意看到它。


具体如果你想要它们:
我要在我的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>

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

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

获得查询结果后,创建一个返回列名的枚举,以及每次迭代的字段值。

例:

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] };
}

在您的代码隐藏中,一旦获得DataTable结果集,请执行以下操作:

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>

样本输出:

样本输出图像

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM