更改 ItemsSource 后绑定 StaticResource

Binding StaticResource after changing ItemsSource

我是 WPF 新手

我有一个简单的 Style 可以为 TextBlock

设置 ForeGroundBackGround

我正在使用 MVVM 方法,oViewModel 可以显示两种颜色。 文本 Test WorksTest Works 工作正常。 但是文本 Test not work 不应用颜色。我认为这是因为我更改了内部 ListBox.

ItemsSource

为什么 StaticResource 在这种情况下不起作用。

<Window x:Class="app_manager.FormScripts.FormScriptsJson"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:app_manager.FormScripts"
        xmlns:json="clr-namespace:CtrlJson.Viewer;assembly=CtrlJson"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        d:DataContext="{d:DesignInstance d:Type=local:CViewScriptsJson, IsDesignTimeCreatable=True}"
        DataContext="{Binding RelativeSource={RelativeSource self}, Path=oViewModel}"
        mc:Ignorable="d"
        x:Name="_this"
        Title="Scripts Results Analysis" WindowState="Maximized" WindowStyle="ToolWindow">

    <Window.Resources>
        <Style x:Key="StyleTxt" TargetType="{x:Type TextBlock}">
            <Setter Property="Foreground" Value="{Binding sColorFore}" />
            <Setter Property="Background" Value="{Binding sColorBack}" />
        </Style>
    </Window.Resources>

    <DockPanel Background="{Binding sColorBack}">
        <TextBlock DockPanel.Dock="Top" Style="{StaticResource StyleTxt}" Text="Test Works"/>

        <Grid x:Name="GirdRoot">
            <Grid.RowDefinitions>
                <RowDefinition MinHeight="450"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition MinHeight="50"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="250"></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>

            <StackPanel
                Grid.Row="0" Grid.Column="0" Grid.RowSpan ="3"
                Margin="3"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch">
                <TextBlock DockPanel.Dock="Top" Style="{StaticResource StyleTxt}" Text="Test Works too"/>
                <ListBox 
                        Grid.Row="0" Grid.Column="0" Name="LstDataJson" ItemsSource="{Binding oLstDataDay}"
                         SelectedItem="{Binding Mode=TwoWay, Path=sDataDaySelected}"
                         IsSynchronizedWithCurrentItem="True">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical" >
                                <TextBlock Text="{Binding}" Style="{StaticResource StyleTxt}"/>
                                <TextBlock Text="Test not work" Style="{StaticResource StyleTxt}"/>
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ListBox>
            </StackPanel>
        </Grid>
    </DockPanel>
</Window>

Test WorksTest Works TooTextBox 都将它们的数据上下文设置为包含 sColorForesColorBack 属性的视图模型。这就是 StyleTxt 可以访问它的原因。但是,ListBox 中的项目将其数据上下文设置为 LstDataJson 中相应的数据对象,其中不包含 sColorForesColorBack 属性,因此它们不能通过绑定解决。

您也可以将这些属性添加到项目中,或者创建第二种样式,使用 RelativeSource 绑定来访问其父项 ListBox 的数据上下文,后者具有自己的数据上下文设置为包含您的颜色属性的视图模型。在您的数据模板中设置此样式 StyleItemTxt 而不是 StyleTxt

<Style x:Key="StyleItemTxt" TargetType="{x:Type TextBlock}">
   <Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.sColorFore}"/>
   <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.sColorBack}"/>
</Style>

另一种选择是从视图模型中完全删除颜色属性并将它们移动到 XAML,例如在资源字典中,因此它们可以在您的应用程序中重用。这种方法通常是有利的,因为它将视图关注点与您的业务逻辑和数据分开。