我已经为这个问题苦苦挣扎了一段时间了,所以我想我应该在这里问一下,看看是否有人可以帮助我。首先,我是 C#、XAML 和 Windows 8 编程新手。
我想做的基本事情是:基于对数据模型的更改(我在 Button_Click 处理程序内的小测试床项目中执行此操作),我想更改 <Style>
中的前景值。我已成功更改 <TextBlock>
中的前景值,但未能成功更改在另一个 <Style>
上运行的 <TextBlock>
中的前景值。
这是我所做的(请原谅冗长,希望它有意义):
我有一个名为 MyColorDataSource 的类,我将其用作 MyPage.xaml 页面中的绑定(bind)目标。这是该类的相关代码:
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);
}
}
您会注意到 MyColorDataSource 中的变量属于 MyColors 类型。这是该类的定义:
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,其中有两个 <TextBlock>
元素,其中一个元素的 Foreground 属性直接绑定(bind)到数据源,其中一个元素使用我尝试绑定(bind)到数据源的 <Style>
。在 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>
我已在 App.xaml.cs 中设置了 DataSource 变量:
public sealed partial class App : Application
{
public static MyColorDataSource ColorDataSource;
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
ColorDataSource = new MyColorDataSource();
}
}
我访问 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
}
如果你还在我身边,谢谢你!发生的情况是,第一个 <TextBlock>
按预期显示,呈深橄榄绿颜色。第二个 <TextBlock>
根本不显示,我假设它的前景默认为黑色(页面背景也是黑色,所以我看不到它)。当我将 <Style>
中的前景值更改为“DarkRed”之类的值时,瞧,它按预期显示。所以 <TextBlock>
肯定存在,但它没有像我想要的那样从 DataModel 获取其前景值。
以前有人遇到过这个问题吗?如果有,你是如何解决的?我真的不想单独更改每个 <TextBlock>
,因为我打算尝试对 <ListView>
中的项目进行样式设置,而且我真的不想迭代所有 <Item>
并一一更改它们的样式。完成了大量的 HTML/CSS/jQuery 工作后,我习惯了能够按类来设置样式,而不是一次一个迭代地设置样式。
预先感谢您提供的任何帮助或建议。
编辑:
我确实设法遇到了一种技术,它使我非常接近我在这里尝试做的事情,部分是在下面的答案的帮助下(再次感谢!)。希望如果其他人也提出类似的问题,这会有所帮助。
<SolidColorBrush x:Key="myBrush" Color="#330000FF" />
<Style TargetType="TextBlock" x:Key="BoundColor">
<Setter Property="Foreground" Value="{StaticResource myBrush}" />
</Style>
然后在我的代码隐藏中,我可以做这样的事情:
((SolidColorBrush)Resources["myBrush"]).Color = Color.FromArgb(64, 255, 0, 0);
这本身并没有将元素的颜色放入数据模型中,但说实话,元素的颜色真的属于数据模型吗?我通常会说不是。
请注意,我没有任何运气使该技术在我尝试使用的“可见性”<Setter>
上工作(我希望 TextBlock 有时隐藏,有时可见),但对于颜色和其他基于对象的<Setter>
s 它工作得很好。根据我所知的一点点,我的假设是这是真的,因为可见性是一个枚举,而不是类。因此,虽然我可以将其放入我的 <Page.Resources>
中:
<Visibility x:Key="TextBlockVisibility">0</Visibility>
这在 <Style>
中:
<Setter Property="Visibility" Value="{StaticResource TextBlockVisibility}" />
我似乎无法以 TextBlockVisibility
会注意到或受到值更改影响的方式更改 <Style>
的值。
最佳答案
抱歉,你不能。与许多非常有用的 WPF 功能一样(您的代码在 WPF 程序中运行得很好),据我所知,Windows Phone 不支持此功能。
也就是说,您可以解决这个问题。最明显的解决方案是首先不使用样式。另一种解决方案是使用“helper”对象作为样式中的实际 setter 值,该对象本身通过样式的 setter 设置的附加属性来管理绑定(bind)。
此技术的示例可以在 David Anson 的网站上找到: The taming of the phone [New SetterValueBindingHelper sample demonstrates its usefulness on Windows Phone 7 (and Silverlight 4)]
使用该示例,您的样式 setter 可能如下所示:
<Setter Property="delay:SetterValueBindingHelper.PropertyBinding">
<Setter.Value>
<delay:SetterValueBindingHelper
Property="Foreground"
Binding="{Binding Brush2.BrushColor}"/>
</Setter.Value>
</Setter>
(注意:我实际上并没有测试您的代码的工作示例;您可能需要对绑定(bind)本身进行一些修改才能获得正确的数据上下文,因为我不确定它是否会正确地继承上下文具有额外间接的页面。)
关于c# - 在 Windows 8.1 的 C# XAML 中,如何将样式绑定(bind)到变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29570591/