我有一个CustomWindow.cs,我使用DataTemplate进行装饰,因为有大量的内容变化。根据MVVM,窗口的DataContext绑定到ViewModel
理想情况下,使用ViewModel中的数据填充其中一些装饰。
我想要实现的结构如下:
<CustomWindow DataContext="{Binding Main, Source={StaticResource Locator}}">
<Content>
</CustomWindow>
DataTemplate可能类似于:
<DataTemplate DataType="{x:Type CustomWindow}">
<ContentPresenter Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type viewModels:HmiViewModelBase}}}">
<ContentPresenter Content="{Binding Content}"/>
</ContentPresenter>
</DataTemplate>
我意识到ContentPresenter中内容的双重定义不会起作用,但却无法想到替代方案。
我将如何实现这样的目标? 我觉得这是一个普遍的问题。
答案 0 :(得分:0)
首先欢迎来到SO。请看下一个概念:1)一个主视图模型在一些可观察集合中包含许多模型(或基于绑定和属性)。 2)可观察集合中的每个模型都有自己的逻辑,并且应该以某种原始方式呈现。 3)主视图模型由主视图(例如列表框)呈现。 4)主视图模型的可观察集合内的每个模式由内容控件呈现,内容控件将为其内容选择一些原始内容模板(这是可观察集合内的模型)。 5)基于模型类型的数据模板可以使用每个wpf控件(或您制作的用户自定义控件)和显示数据。这是代码: 1. XAML代码:
<Window x:Class="DataTemplateSOHelpAttempt.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dataTemplateSoHelpAttempt="clr-namespace:DataTemplateSOHelpAttempt"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<dataTemplateSoHelpAttempt:MainViewModel/>
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type dataTemplateSoHelpAttempt:OrangeObject}">
<TextBlock Text="{Binding Description}" Background="Orange"></TextBlock>
</DataTemplate>
<DataTemplate DataType="{x:Type dataTemplateSoHelpAttempt:GreenObject}">
<TextBlock Text="{Binding Description}" Background="GreenYellow"></TextBlock>
</DataTemplate>
<DataTemplate DataType="{x:Type dataTemplateSoHelpAttempt:BlueObject}">
<TextBlock Text="{Binding Description}" Background="CadetBlue"></TextBlock>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Objects}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ContentControl Content="{Binding }"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid></Window>
2。查看型号代码:
public class MainViewModel:BaseObservableObject
{
public MainViewModel()
{
Objects = new ObservableCollection<BaseDataObject>(new List<BaseDataObject>
{
new BlueObject{Description = "Hello I'm blue object!!!"},
new OrangeObject{Description = "Hello I'm orange object!!!"},
new GreenObject{Description = "Hello I'm green object!!!"},
new OrangeObject{Description = "Hello I'm anoter orange object!!!"},
new BlueObject{Description = "Hello I'm another blue object!!!"},
new OrangeObject{Description = "Hello I'm another orange again object!!!"},
new GreenObject{Description = "Hello I'm another green object!!!"},
new OrangeObject{Description = "Hello I'm again another orange object!!!"},
});
}
public ObservableCollection<BaseDataObject> Objects { get; set; }
}
3。型号代码:
public abstract class BaseDataObject:BaseObservableObject
{
public abstract string Description { get; set; }
}
public class OrangeObject:BaseDataObject
{
private string _description;
public override string Description
{
get { return _description; }
set
{
_description = value;
OnPropertyChanged();
}
}
}
public class BlueObject:BaseDataObject
{
private string _description;
public override string Description
{
get { return _description; }
set
{
_description = value;
OnPropertyChanged();
}
}
}
public class GreenObject:BaseDataObject
{
private string _description;
public override string Description
{
get { return _description; }
set
{
_description = value;
OnPropertyChanged();
}
}
}
4。基本的INotifyPropertyChanged实现(使用CallerMemberName的4.5 dotNet版本):
public class BaseObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
{
var propName = ((MemberExpression)raiser.Body).Member.Name;
OnPropertyChanged(propName);
}
protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(name);
return true;
}
return false;
}
}
这就是全部,复制/过去,调试和使用。如果你的代码有问题我会很乐意提供帮助。如果答案有帮助,请将其标记为已回答。 的问候,