在MVVM中,每个View都有一个ViewModel.一个视图我理解为一个Window,Page或UserControl,你可以附加一个ViewModel,视图从中获取其数据.
但DataTemplate也可以呈现ViewModel的数据.
所以我理解DataTemplate是另一个"View",但似乎存在差异,例如Windows,Pages和UserControls可以定义自己的.dll,一个类型与DataContect绑定另一个通过附加模板使Windows,Pages ,UserControls可以通过ServiceLocator/Container等动态附加到ViewModels .
当在UI上呈现ViewModel的数据时,DataTemplates与Windows/Pages/UserControls有何不同?除了这四种之外还有其他类型的"观点"吗?
我希望它ContentTemplate根据中的值而变化DataTrigger.
是的,我考虑使用a DataTemplateSelector,但现在我需要一个DataTrigger或更好的说a MultiDataTrigger.
请看下面的示例应用程序,DataTemplate不会改变:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:WpfApplication1">
<StackPanel>
<CheckBox IsChecked="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Content="BoolProperty"/>
<ContentControl Content="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}">
<ContentControl.ContentTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Content="Template 1"/>
</DataTemplate>
</ContentControl.ContentTemplate>
<ContentControl.Resources>
<DataTemplate x:Key="Template2">
<CheckBox IsChecked="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Content="Template 2"/>
</DataTemplate>
</ContentControl.Resources>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource Template2}"/>
</DataTrigger> …Run Code Online (Sandbox Code Playgroud) 我有一个enum让我们说
enum MyEnum
{
FirstImage,
SecondImage,
ThirdImage,
FourthImage
};
Run Code Online (Sandbox Code Playgroud)
我已将这个Enum绑定到XAML中的组合框中.
在定义组合框时,我已经定义了一个combox的ItemTemplate来获取两个UI元素:
我在XAML中做了这么多.
我想知道在哪里可以指定与组合框中的每个Enum值项目相对应的图像?这可能通过数据触发吗?
如果有人为此场景设置了XAML,我真的很感激.
提前谢谢了
我已经制作了一个示例演示VS 2010 RC示例项目,因为在我的生产项目中我使用MVVM时遇到了同样的错误.
在我的示例演示项目中,我只使用Code-behind而没有第三方依赖,因此您可以在此处下载演示项目并自行运行:http://www.sendspace.com/file/mwx7wv
现在问题:当我点击女孩/男孩按钮时,它应该切换datatemplate,不是吗?
我错了什么?
好的,我在这里也提供了一个代码片段:
代码隐藏在MainWindow.cs:
namespace ContentTemplateSelectorDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Person person;
public MainWindow()
{
InitializeComponent();
person = new Person(){ Gender = "xxx"};
person.IsBoy = true;
ContentGrid.DataContext = person;
}
private void btnBoys_Click(object sender, RoutedEventArgs e)
{
person.IsBoy = true;
person.IsGirl = false;
this.ContentGrid.DataContext = person;
}
private void btnGirls_Click(object sender, RoutedEventArgs e)
{
person.IsGirl = true;
person.IsBoy = …Run Code Online (Sandbox Code Playgroud) 我有一个DataTemplate由是源自媒体元素控制的MediaElementBase从WPF媒体工具库.该MediaElementBase类提供了两个属性,LoadedBehavior并UnloadedBehavior允许用户指定当元素加载/卸载会发生什么.
我发现在a DataTemplate(如下)中使用它时,这些属性在卸载模板时会重置为默认值,但在Unloaded调用事件之前,意味着只UnloadedBehavior执行默认值:
<DataTemplate DataType="{x:Type Channels:AnalogChannel}">
<Controls:AnalogTvGraphFileElement
LoadedBehavior="Play"
UnloadedBehavior="Stop"
Channel="{Binding}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
当控件只是页面上的元素并Unloaded通过正常的导航事件发生时,不会发生这种情况.
调试DependencyPropertyChanged EventHandler显示内部方法System.Windows.StyleHelper.InvalidatePropertiesOnTemplateNode(在PresentationFramework.dll中)检查是否DependencyProperty可能继承,如果不是,则使其无效.果然,更改LoadedBehavior/ UnloadedBehavior添加的属性元数据会FrameworkPropertyMetadataOptions.Inherits在模板更改时阻止此属性重置.
有谁知道为什么会这样?我可以添加Inherits标志作为解决方法,因为此元素没有受此影响的子元素,但我想知道为什么/是否正确的做法.
如果您正在了解有关我正在做什么以及为什么要更改的更多信息,DataTemplates您可以查看此问题以获取说明.
我尝试使用祖先的对象设置Foreground颜色,但它没有任何效果.我甚至使用了更改超链接前景的提示而没有丢失悬停颜色,但它没有任何区别 - 我仍然得到一个悬停时为红色的蓝色超链接.HyperlinkStyleResourcesBasedOn
这是我的控件的XAML,包括ItemsControl使用超链接显示其项目的XAML :
<StackPanel Background="Red" TextElement.Foreground="White">
<StackPanel.Resources>
<Style TargetType="Hyperlink" BasedOn="{StaticResource {x:Type Hyperlink}}">
<Setter Property="Foreground" Value="Yellow"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBlock>Data import errors</TextBlock>
<ItemsControl ItemsSource="{Binding Errors}"/>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
而且这些项目ItemsControl正在取得以下成果DataTemplate:
<DataTemplate DataType="{x:Type Importer:ConversionDetailsMessage}">
<TextBlock>
<Run Text="{Binding Message, Mode=OneTime}"/>
<Hyperlink Command="Common:ImportDataCommands.ExplainConversionMessage" CommandParameter="{Binding}">
<Run Text="{Binding HelpLink.Item2, Mode=OneTime}"/>
</Hyperlink>
</TextBlock>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
值得一提的,那就是,我不想只是上直接设置不同颜色Hyperlink的DataTemplate.这是因为模板将被许多不同的ItemsControl对象使用,其中大部分将在白色背景上,因此可以使用标准的超链接颜色.(请注意,上面XAML中的那个具有红色背景.)
简而言之,我不希望 …
我有一个非常简单的例子:WPF表单应用程序,包含带有数据的字典:
Dim dict As New Collections.Generic.Dictionary(Of String, String)
Private Sub MainWindow_Loaded() Handles Me.Loaded
dict.Add("One", "1")
dict.Add("Two", "2")
dict.Add("Three", "3")
lst1.ItemsSource = dict
End Sub
Run Code Online (Sandbox Code Playgroud)
在表单上我有一个ListBox(名为"lst1"),它使用"dict"作为项目源:
<ListBox x:Name="lst1">
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Value}"
TextSearch.Text="{Binding Path=Key, Mode=OneWay}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
我还有一个非绑定的ListBox,手动预先填充值:
<ListBox>
<Label TextSearch.Text="One" Content="1" />
<Label TextSearch.Text="Two" Content="2" />
<Label TextSearch.Text="Three" Content="3" />
</ListBox>
Run Code Online (Sandbox Code Playgroud)
因此,当我启动应用程序时,它看起来像这样:

如果我尝试通过键入"one","two"或"three"来使用键盘导航项目,我只能在非绑定列表框中成功.绑定列表框失败.
一些评论:1.)如果我在绑定列表框中按"[",焦点会以循环方式从一个项目更改为一个项目:它从1到2,从2到3,从3到1,再从1再到2 2.)我已经使用Snoop检查了应用程序.我在绑定和非绑定列表框之间找到了一个区别.两个列表框都在Label控件上设置了TextSearch.Text属性(在ItemsPresenter内).但对于非约束情况:TextSearch.Text属性的"值源"是"本地".对于约束情况:"value source"是"ParentTemplate".
PS(和NB) 我知道我可以在列表框中使用TextSearch.TextPath,但这不是我需要的:)另外,为ListViewItem设置TextSearch.Text属性(通过使用Style)也无济于事.
我在DataTemplate中有一些控件,我想控制它的按下状态行为.我做了以下我只是在DataTemplate中放入VisualStateManager但它似乎不起作用.我想我可以理解下面要做的事情.是否可以在DataTemplate标签内部进行内联?
<ItemsControl ItemsSource="{Binding Items}">
....
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid ...>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
...
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderThickness" Storyboard.TargetName="GridItemBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="3"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" ...>
...
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud) silverlight xaml datatemplate visualstatemanager windows-phone-7
我有一个MenuItem类型的WPF控件模板:
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border Background="{TemplateBinding Background}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentControl Content="{TemplateBinding Header}"
Margin="5"
Grid.Column="1" />
<Path Grid.Column="2"
x:Name="Indicator"
Data="M1,1 L1,9 9,5Z"
Fill="{StaticResource GlyphBrush}"
Margin="4"
Visibility="Hidden"
VerticalAlignment="Center" />
<Popup Name="PART_Popup"
Placement="Right"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Grid.Column="0"
Grid.ColumnSpan="2"
HorizontalOffset="3"
VerticalOffset="-1">
<Border Background="Transparent">
<ContentControl Style="{StaticResource PopupContentStyle}">
<ItemsPresenter/>
</ContentControl>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="true">
<Setter Property="Background" …Run Code Online (Sandbox Code Playgroud) 我已经创建了一个DataTemplateSelector,它使用已知接口的集合进行初始化.如果传入选择器的项目实现其中一个接口,则返回关联的数据模板.
首先,这是有问题的ICategory接口......
public interface ICategory
{
ICategory ParentCategory { get; set; }
string Name { get; set; }
ICategoryCollection Subcategories { get; }
}
Run Code Online (Sandbox Code Playgroud)
这是基于基类或接口而不仅仅是特定具体类匹配的DataTemplateSelector ...
[ContentProperty("BaseTypeMappings")]
public class SubclassedTypeTemplateSelector : DataTemplateSelector
{
private delegate object TryFindResourceDelegate(object key);
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var frameworkElement = container as FrameworkElement;
foreach(var baseTypeMapping in BaseTypeMappings)
{
// Check if the item is an instance of, a subclass of,
// or implements the interface specified in BaseType
if(baseTypeMapping.BaseType.IsInstanceOfType(item))
{
// …Run Code Online (Sandbox Code Playgroud) c# wpf datatemplate hierarchicaldatatemplate datatemplateselector
datatemplate ×10
wpf ×9
.net ×3
binding ×2
c# ×2
datatrigger ×2
xaml ×2
data-binding ×1
hyperlink ×1
menuitem ×1
mvvm ×1
silverlight ×1
styles ×1
text-search ×1
viewmodel ×1