0

我为多个列表框项和里面的一些文本块创建了一个模板。在设置中,用户可以将应用程序的背景更改为黑色或白色(然后文本块的前景色应相应更改为相反的颜色)。如何将文本块文本绑定到一个属性(项目列表(observablecollection))和前景到另一个属性(带有颜色转换器),它不在同一个数据上下文中(但在设置数据上下文中)?

我正在尝试做的事情:

<DataTemplate x:Key="ArticleItemTemplateClassic">
        <Grid>
            <!-- ... --->
             <TextBlock Text="{Binding Description}"
                        Foreground="{Binding SettingsFile.BlackBackgroundEnabled,
                        Converter={StaticResource InverseBackgroundColorConverter}}"/>
            <!-- The Context of the Foreground (SettingsFile.BlackBackgroundEnabled) -->
            <!-- should be not the same as where I bind Description -->
            </StackPanel>
            <!-- ... --->
        </Grid>
    </DataTemplate>

谢谢!

4

2 回答 2

0

DataContext如果您被迫这样做,您可以为每个项目显式指定不同的。虽然我不确定为什么会有两个与外观一致的属性DataTemplate位于不同的容器中。

于 2013-03-02T17:25:45.763 回答
0

为此,您需要为 Foreground 属性指定绑定的来源。这可以通过多种方式完成,但一个示例是将 Settings 类公开为资源。

例如:

<Grid x:Name="LayoutRoot">
    <Grid.Resources>
        <!-- If you want to use SettingsFile as a static, you might want to expose an accessor/wrapper class for it here instead. -->
        <settings:SettingsFile x:Name="SettingsFileResource" />
    </Grid.Resources>
    <ListBox ItemsSource="{Binding MyItems}">
        <ListBox.ItemTemplate>
            <DataTemplate x:Key="ArticleItemTemplateClassic">
                <Grid>
                    <!-- ... -->
                    <TextBlock Text="{Binding Description}"
                               <!-- Now change your Binding Path to the target property, and set the source to the resource defined above. -->
                    Foreground="{Binding BlackBackgroundEnabled, Source={StaticResource SettingsFileResource}, Converter={StaticResource InverseBackgroundColorConverter}}"/>

                    <StackPanel />
                    <!-- ... -->
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

或者,为此使用 AttachedProperty 可能会更干净。例如:

public static bool GetBlackBackgroundEnabled(DependencyObject obj)
{
    return (bool)obj.GetValue(BlackBackgroundEnabledProperty);
}

public static void SetBlackBackgroundEnabled(DependencyObject obj, bool value)
{
    obj.SetValue(BlackBackgroundEnabledProperty, value);
}

// Using a DependencyProperty as the backing store for BlackBackgroundEnabled.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty BlackBackgroundEnabledProperty =
    DependencyProperty.RegisterAttached("BlackBackgroundEnabled", typeof(bool), typeof(Control), new PropertyMetadata(false, (s, e) =>
        {
            Control target = s as Control;
            SolidColorBrush brush = new SolidColorBrush();

            // Logic to determine the color goes here
            if (GetBlackBackgroundEnabled(target))
            {
                brush.Color = something;
            }
            else
            {
                brush.Color = somethingElse;
            }

            target.Foreground = brush;
        }));

然后你会像这样使用它:

<TextBlock settings:SettingsFile.BlackBackgroundEnabled="True" />
于 2013-03-02T18:53:15.640 回答