WPF-在后面的代码中更改样式 [英] WPF - Change a style in code behind
问题描述
我有一个列表框,显示TFS查询的结果。我想在后面的代码中更改ListBoxItem的样式,以使查询结果中包含这些列。
I have a list box that displays the results of a TFS Query. I want to change the style of the ListBoxItem in the code behind to have the columns that are included in the query results.
ListBoxItem的样式在Windows中定义。重新分配部分。我已经尝试过:
The style for the ListBoxItem is defined in my Windows.Resoruces Section. I have tried this:
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提供了空值)。
But the ContentTemplate is null. I got that code from here, then modified it with the LoadContent call (the orginal code gave null for the ContentPresenter).
任何方式。如果您知道在后面的代码中更改现有样式的方法,我将很乐意看到它。
Anyway. If you know a way to change an existing style in the code behind I would love to see it.
如果您要想要它们:
我打算以ListBoxItem样式使用WrapPanel。这就是我想向其中添加多余的TextBlock项的地方。
Specifics if you want them:
I am going for WrapPanel in my ListBoxItem Style. This is what I want to add the extra TextBlock items to.
这是我的风格的一部分:
Here is part of my style:
<!--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>
推荐答案
您在这里遇到了麻烦,试图直接在后台代码中操作视觉元素。有一个非常简单的解决方案涉及数据绑定。
You're going against the grain here, trying to manipulate visual elements directly in code-behind. There's a much simple solution involving data binding.
我将提供常规解决方案,因为我不知道您的解决方案的具体细节。
I'll provide the general solution because I don't know the specifics of your solution.
获得查询结果后,创建一个枚举,该枚举返回每次迭代的列名和字段值。
Once you get your query results, create an enumeration that returns a column name, and a field value for each iteration.
示例:
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结果集,
And in your code-behind, once you get your DataTable result set, do this:
myResultsList.ItemsSource = EnumerateResultSet(myDataTable);
XAML可能看起来像这样:
The XAML might look like this:
<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>
样本输出:
这篇关于WPF-在后面的代码中更改样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!