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