在C#XAML for Windows 8.1中,如何将样式绑定到变量?

在C#XAML for Windows 8.1中,如何将样式绑定到变量?,c#,xaml,windows-phone-8,syntax,C#,Xaml,Windows Phone 8,Syntax,我已经用我的头撞这个有一段时间了,所以我想我应该在这里问一下,看看有没有人能帮我一把。首先,我不熟悉C#、XAML和Windows8编程 我想做的基本事情是:基于对数据模型的更改(这是我在按钮点击处理程序中的小测试床项目中所做的),我想更改中的前景值。我成功地更改了中的前景值,但在另一个上运行的上没有 以下是我所做的(请原谅我的长篇大论,希望它有意义): 我有一个名为MyColorDataSource的类,我在MyPage.xaml页面中将它用作绑定目标。下面是该类的相关代码: public c

我已经用我的头撞这个有一段时间了,所以我想我应该在这里问一下,看看有没有人能帮我一把。首先,我不熟悉C#、XAML和Windows8编程

我想做的基本事情是:基于对数据模型的更改(这是我在按钮点击处理程序中的小测试床项目中所做的),我想更改
中的前景值。我成功地更改了
中的前景值,但在另一个
上运行的
上没有

以下是我所做的(请原谅我的长篇大论,希望它有意义):

我有一个名为MyColorDataSource的类,我在MyPage.xaml页面中将它用作绑定目标。下面是该类的相关代码:

public class MyColorDataSource 
{
    private MyColors _brush1;

    public MyColors Brush1
    {
        get { return _brush1; }
        set { _brush1 = value; }
    }

    private MyColors _brush2;

    public MyColors Brush2
    {
        get { return _brush2; }
        set { _brush2 = value; }
    }


    public MyColorDataSource()
    {
        _brush1 = new MyColors();
        _brush2 = new MyColors();

        _brush1.BrushColor= new SolidColorBrush(Colors.DarkRed);
        _brush2.BrushColor = new SolidColorBrush(Colors.Pink);
    }
}
public class MyColors : INotifyPropertyChanged
{

    private SolidColorBrush _brushColor;

    public SolidColorBrush BrushColor
    {
        get { return _brushColor; }
        set {
            if (value != _brushColor)
            {
                _brushColor = value;
                NotifyPropertyChanged("BrushColor");
            }
        }
    }

    #region INotifyPropertyChanged Members

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            Debug.WriteLine("in NotifyPropertyChanged for " + propertyName);
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}
您会注意到MyColorDataSource中的变量属于MyColors类型。下面是该类的定义:

public class MyColorDataSource 
{
    private MyColors _brush1;

    public MyColors Brush1
    {
        get { return _brush1; }
        set { _brush1 = value; }
    }

    private MyColors _brush2;

    public MyColors Brush2
    {
        get { return _brush2; }
        set { _brush2 = value; }
    }


    public MyColorDataSource()
    {
        _brush1 = new MyColors();
        _brush2 = new MyColors();

        _brush1.BrushColor= new SolidColorBrush(Colors.DarkRed);
        _brush2.BrushColor = new SolidColorBrush(Colors.Pink);
    }
}
public class MyColors : INotifyPropertyChanged
{

    private SolidColorBrush _brushColor;

    public SolidColorBrush BrushColor
    {
        get { return _brushColor; }
        set {
            if (value != _brushColor)
            {
                _brushColor = value;
                NotifyPropertyChanged("BrushColor");
            }
        }
    }

    #region INotifyPropertyChanged Members

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            Debug.WriteLine("in NotifyPropertyChanged for " + propertyName);
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}
这是我编写的XAML,包含两个
元素,其中一个元素的前台属性直接绑定到数据源,另一个元素使用我试图绑定到数据源的
。在MyPage.xaml中:

<Page.Resources>
    <Style TargetType="TextBlock" x:Key="BoundColor">
        <Setter Property="Foreground" Value="{Binding Brush2.BrushColor}" />
    </Style>
</Page.Resources>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <TextBlock x:Name="TextBlockToFormatWithBinding" Text="Direct Binding" Foreground="{Binding BrushColor}" />
    <TextBlock x:Name="TextBlockToFormatWithStyleBinding" Text="Binding through style" Style="{StaticResource BoundColor}"/>
</StackPanel>
我访问MyPage.xaml.cs中的数据源:

public MyPage()
{
    this.InitializeComponent();
    App.ColorDataSource.Brush1.BrushColor = new SolidColorBrush(Colors.DarkOliveGreen);
    App.ColorDataSource.Brush2.BrushColor = new SolidColorBrush(Colors.DarkKhaki);
    this.DataContext = App.ColorDataSource;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
    TextBlockToFormatWithBinding.DataContext = App.ColorDataSource.Brush1;
    // TextBlockToFormatWithStyleBinding.DataContext = App.ColorDataSource.Brush2; // tried this, it did nothing
}
如果你还和我在一起,谢谢你!所发生的事情是,第一个
按预期显示,呈暗绿色。第二个
根本不显示,我假设它的前景默认为黑色(页面背景也是黑色的,所以我看不见)。当我将
中的前景值更改为类似“DarkRed”的值时,瞧,它会按预期显示。因此,
确实存在,但它并没有像我希望的那样从数据模型中获得其前景价值

以前有没有人碰到过这个问题?如果是的话,你是如何解决的?我真的不想单独更改每个
,因为我打算尝试在
中设置项目的样式,我真的不想遍历所有
并逐个更改它们的样式。在完成了大量的HTML/CSS/jQuery之后,我习惯于按类而不是一次一个迭代地为事物设置样式

提前感谢您提供的任何帮助或建议

编辑:

我确实遇到了一种技术,它让我非常接近我在这里要做的事情,部分是在下面答案的帮助下(再次感谢!)。希望如果其他人提出类似的问题,这会有所帮助

    <SolidColorBrush x:Key="myBrush" Color="#330000FF" />
    <Style TargetType="TextBlock" x:Key="BoundColor">
        <Setter Property="Foreground" Value="{StaticResource myBrush}" />
    </Style>
这本身并不会将元素的颜色放在数据模型中,但老实说,元素的颜色真的属于数据模型吗?我通常会说,事实并非如此

请注意,我没有任何运气让这项技术在“可见性”上起作用,我试着把它放在“可见性”上(我希望文本块有时隐藏,有时可见),但对于颜色和其他基于对象的
s,效果很好。根据我所知的一点,我的假设是这是真的,因为可见性是一个枚举,而不是类。因此,虽然我可以将其放入我的

    <Setter Property="Visibility" Value="{StaticResource TextBlockVisibility}" />
0
中:

    <Setter Property="Visibility" Value="{StaticResource TextBlockVisibility}" />


我似乎无法改变
TextBlockVisibility
的值,使
注意到值的变化或受其影响。

抱歉,但您不能。与许多非常有用的WPF功能一样(您的代码在WPF程序中工作正常),这在Windows Phone上是不受支持的

也就是说,你可以解决这个问题。最明显的解决方案是首先不要使用样式。另一种解决方案是使用“helper”对象作为样式中的实际setter值,它本身通过样式的setter设置的附加属性来管理绑定

David Anson的网站上提供了该技术的一个示例,如下所示:

使用该示例,您的样式设置器可能如下所示:

((SolidColorBrush)Resources["myBrush"]).Color = Color.FromArgb(64, 255, 0, 0);
<Setter Property="delay:SetterValueBindingHelper.PropertyBinding">
  <Setter.Value>
    <delay:SetterValueBindingHelper
      Property="Foreground"
      Binding="{Binding Brush2.BrushColor}"/>
  </Setter.Value>
</Setter>


(注意:我实际上没有为您的代码测试一个工作示例;您可能需要稍微调整绑定本身以获得正确的数据上下文,因为我不确定它是否会通过额外的间接方式从页面正确继承上下文。)

感谢您的提示,我将尝试一下!关于代码的一个问题是,使用延迟:xmlns。。。“delay:”有什么特别的地方吗?或者这只是该技术实现中使用的任意名称吗?如果是后者,它在标签中的定义是什么?我还没有读过你链接的文章,因此如果有答案,请忽略这个问题。
delay
与其他XML名称空间名称一样,只是分配给XAML中使用的名称空间的任意名称。它是通过
xmlns
声明的;我之所以使用它,只是因为这是链接引用(即您尚未阅读的文章:)的示例XAML中使用的名称空间名称。有些人喜欢缩短名字,例如,
d
而不是
delay
,其他人喜欢更具描述性的名字。您可以在XAML中使用您喜欢的任何东西,只要确保使用方法与您通过
xmlns
声明的内容一致即可。在阅读本文时,它似乎非常特定于Silverlight。你知道这些技术是否适用于非SL应用程序吗?@KyleHumfeld:我自己还没有尝试过这种实现。然而,我在Windows Phone上使用了附加属性的方法来处理其他事情,并且它是有效的。请注意,作者提到了一个不受支持的功能(行走部件),但您不太可能需要该特定零件。因此,是的,我希望基本技术,如果不是实际的代码示例(最坏的情况下,我希望在Windows Phone下编译时需要一些调整)能够在Windows Phone上工作。谢谢,@PeterDuniho,我相信