在我的WPF应用程序中,我有一个Observable抽象基类Test
集合,实际上它的衍生类SqlTest
和ConfigTest
已经完整。
我有一个组合框,允许用户从可观察集合中选择一个项目,并且根据所选测试的类型我想要不同的控件。
我尝试过使用DataTemplates但是还没有设法让它们在列表以外的任何地方工作。
test.cs中
public abstract class Test
{
public string Number { get; set; } // A string as test numbers can contain multiple decimal points depending on the section
public string Description { get; set; }
public string Condition { get; set; }
public string Result { get; set; }
}
查看模型
public class MainWindowViewModel : INotifyPropertyChanged
{
public ObservableCollection<Test> Tests { get; set; } = new ObservableCollection<Test>();
public Test SelectedTest
{
get { return _selectedTest; }
set
{
_selectedTest = value;
OnPropertyChanged("SelectedTest");
}
}
private Test _selectedTest;
public MainWindowViewModel()
{
Tests.Add(new SqlTest("Change Me", "Check Me", "2", "A Test", "Condition", "Result"));
Tests.Add(new ConfigTest("key", "value", "orig", "1.10", "Test2", "this is a result", "or is it?"));
Tests.Add(new SqlTest("Change Me", "Check Me", "2", "A Test", "Condition", "Result"));
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我的xaml
<ComboBox Grid.Row="0" ItemsSource="{Binding Tests}" SelectedItem="{Binding SelectedTest}" IsSynchronizedWithCurrentItem="True" SelectedIndex="0">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock><Run Text="{Binding Number}" /><Run Text=" "/><Run Text="-" /><Run Text=" "/><Run Text="{Binding Description}" /></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!-- The Conditions of the test -->
<TextBlock Grid.Row="1" Margin="0, 5, 0, 0" Text="{Binding SelectedTest.Condition}" TextWrapping="Wrap" />
<!-- The Result of the test -->
<TextBlock Grid.Row="2" Margin="0, 5, 0, 0" Text="{Binding SelectedTest.Result}" TextWrapping="Wrap" />
答案 0 :(得分:2)
这是一个非常简单的例子,我会在几分钟内为你准备好。
MainWindowVm
是主窗口的视图模型。它有2个属性,第一个是Thing
的列表,第二个是选定的Thing
。主窗口将组合框绑定到Things
,SelectedThing
为SelectedItem
。 ContentControl
也绑定了SelctedThing
,其资源中定义了2 DataTemplates
。 DataType
会自动使用模板的ContentControl
属性,并在SelectedThing
更改时与其内容类型进行比较。模板内部的任何标记都显示在组合框下方。
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="525"
Height="350"
mc:Ignorable="d">
<Window.DataContext>
<local:MainWindowVm />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ComboBox Grid.Row="0"
ItemsSource="{Binding Path=Things}"
SelectedItem="{Binding Path=SelectedThing}" />
<ContentControl Grid.Row="1" Content="{Binding Path=SelectedThing}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type local:Thing1}">
<StackPanel>
<TextBlock Text="This Is the template for Thing1" />
<Button Content="This is a button!" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Thing2}">
<StackPanel>
<TextBlock Text="This Is the template for Thing2" />
<TextBox Text="Enter some text" />
</StackPanel>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Grid>
</Window>
MainWindowVm.cs:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WpfApplication1
{
class MainWindowVm : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MainWindowVm()
{
Things = new ObservableCollection<object>();
Things.Add(new Thing1());
Things.Add(new Thing2());
}
public ObservableCollection<Object> Things { get; set; }
private Object _selectedThing;
public Object SelectedThing
{
get
{
return _selectedThing;
}
set
{
if (value != _selectedThing)
{
_selectedThing = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedThing)));
}
}
}
}
}
Thing1
和Thing2
只是空类。