我一直在教自己WPF,而且我还在学习基本概念和术语。如果这个问题的标题没有正确的话,请原谅我。
我有以下XAML,HierarchicalDataTemplate
的一部分绑定到ViewModelBase
类型的对象:
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding PrefixStyle.Text}"
FontWeight="{Binding PrefixStyle.Weight}"
Foreground ="{Binding PrefixStyle.Foreground}"
Margin="0,0,3,0"/>
<TextBlock Text="{Binding ValueStyle.Text}"
FontWeight="{Binding ValueStyle.Weight}"
Foreground ="{Binding ValueStyle.Foreground}"
Margin="0,0,3,0"/>
<TextBlock Text="{Binding SuffixStyle.Text}"
FontWeight="{Binding SuffixStyle.Weight}"
Foreground ="{Binding SuffixStyle.Foreground}"
Margin="0,0,3,0"/>
...
</StackPanel>
ViewModelBase
具有XAML中引用的相应属性:
public TextBlockStyle PrefixStyle...
public TextBlockStyle ValueStyle...
public TextBlockStyle SuffixStyle...
public class TextBlockStyle : INotifyPropertyChanged
{
public string Text...
public FontWieght Weight...
public Brush Foreground
}
如何在XAML中仅将TextBlock
到TextBlockStyle
的绑定定义为一次,并且不必像上面那样明确绑定每个TextBlock
属性?所以我可以为每个TextBlock
添加一行:
<StackPanel Orientation="Horizontal">
<TextBlock Source="{Binding PrefixStyle}" />
<TextBlock Source="{Binding ValueStyle}" />
<TextBlock Source="{Binding SuffixStyle}" />
...
</StackPanel>
我只是不知道从哪里开始。我需要继承TextBlock吗?使用BindingGroup?
这一定是程序员遇到的常见问题 - 所以如果以前曾经问过这个问题,我很抱歉。我尝试过搜索,但我对WPF这么新,我不知道如何正确地表达我的问题。
答案 0 :(得分:2)
您使用隐式样式设置&#34; global&#34;整个应用程序的风格。这通常在App.xaml
内的ResourceDictionary
文件中完成。
<Style TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource TextBlockStyle}">
<Setter Property="FontWeight"
Value="Bold">
</Setter>
<Setter Property="Foreground"
Value="Red">
</Setter>
</Style>
如果您继续使用您关注的方法(我不会),您可以将您的二传手更改为:
<Setter Property="FontWeight"
Value="{Binding Weight}">
</Setter>
然后,除非您为控件定义更本地的显式/隐式样式,否则应用程序中的所有TextBlock
都将使用该样式。
编辑以详细说明评论:
我还使用TreeView
和HierarchicalDataTemplate
。以MVVM方式思考,TreeView
(父/子)中的每个项目都应该代表某种模型。例如,想想Windows资源管理器。其中的每个项目都是MVVM世界中的Folder
或Drive
。 Folder
和Drive
不会有不同的字体粗细/颜色/尺寸特征,因为它们的所有视图都相关。
在我们的例子中,你会有这样的东西:
public class BaseItem : ViewModel
{
public ObservableCollection<BaseItem> Children { .... }
public bool IsSelected { .... }
public string Title { .... }
}
由于文件夹可以容纳更多文件夹,并且驱动器可以容纳文件夹,您可以这样:
public class DriveVM : BaseItem { }
public class FolderVM : BaseItem { }
你要在Children.Add(new FolderVM(folder));
内做DriveVM
,这会在驱动器下显示一个文件夹。问题是这可能变得相当复杂。简而言之,我认为继承是使用TreeView
的关键。
另一种选择是这样的:
<Style x:Name="PrefixTextBlockStyle"
TargetType="{x:Type TextBox}">
<Setter Property="FontWeight"
Value="Bold" />
<Setter Property="Foreground"
Value="Red" />
<Setter Property="Text"
Value="{Binding Text}"
<Setter Property="Margin"
Value="0 0 3 0" />
</Style>
<Style x:Name="SuffixTextBlockStyle"
TargetType="{x:Type TextBox}">
<Setter Property="FontWeight"
Value="Italic" />
<Setter Property="Foreground"
Value="Orange" />
<Setter Property="Text"
Value="{Binding Text}" />
<Setter Property="Margin"
Value="0 0 3 0" />
</Style>
然后在HierarchicalDataTemplate
执行:
<StackPanel Orientation="Horizontal">
<TextBlock DataContext="{Binding Prefix}"
Style="{StaticResource PrefixTextBlockStyle} ">
....
</StackPanel>
答案 1 :(得分:0)
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{Binding Text}" />
<Setter Property="FontWeight" Value="{Binding Weight}" />
<Setter Property="Foreground " Value="{Binding Foreground}" />
<Setter Property="Margin" Value="0,0,3,0" />
</Style>
</StackPanel.Resources>
<TextBlock DataContext="{Binding PrefixStyle}"/>
<TextBlock DataContext="{Binding ValueStyle}"/>
<TextBlock DataContext="{Binding SuffixStyle}"/>
...
</StackPanel>
或在app.xaml中使用全局命名样式:
<Application>
<Application.Resources>
<Style x:Key="MyTextBlockStyle" TargetType="TextBlock">
<Setter Property="Text" Value="{Binding Text}" />
<Setter Property="FontWeight" Value="{Binding Weight}" />
<Setter Property="Foreground " Value="{Binding Foreground}" />
<Setter Property="Margin" Value="0,0,3,0" />
</Style>
</Application.Resources>
</Application>
其他地方的用法:
<Window>
<StackPanel>
<!-- Single textblock with explicit style -->
<TextBlock DataContext="Blah" Style="{StaticResource MyTextBlockStyle}" />
<!-- Multiple textblocks with implicit style -->
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="TextBlock" BasedOn={StaticResource MyTextBlockStyle}" />
</StackPanel.Resources>
<TextBlock DataContext="{Binding PrefixStyle}"/>
<TextBlock DataContext="{Binding ValueStyle}"/>
<TextBlock DataContext="{Binding SuffixStyle}"/>
...
</StackPanel>
</Window>