我會提出不同要對此。相反,考慮動態地添加屬性視圖/模型,我會考慮增加有關這些屬性對視圖模型的列表。然後該列表將被綁定到ItemsControl
,其模板看起來像是TextBox
。
所以您的視圖模型會對它的屬性爲您要檢查的「東西」。在此屬性的設置器中,使用反射枚舉您感興趣的屬性,並將某種FieldInfo
類(您創建的)的實例添加到具有綁定的屬性列表中。
這有藏在心裏所有MVVM兼容太的利益,而且也沒有必要動態創建控件用自己的代碼。下面
的例子使用我自己的MVVM庫(作爲NuGet包),而不是caliburn.micro,但它應該是足夠相似遵循的基本思路。該示例的完整源代碼可以從this BitBucket repo下載。
正如您在附帶的屏幕截圖中看到的那樣,搜索字段是在視圖中動態創建的,而視圖中沒有任何代碼。一切都在視圖模型上完成。這也使您可以輕鬆訪問用戶輸入的數據。
視圖模型:
namespace DynamicViewExample
{
class MainWindowVm : ViewModel
{
public MainWindowVm()
{
Fields = new ObservableCollection<SearchFieldInfo>();
SearchableTypes = new ObservableCollection<Type>()
{
typeof(Models.User),
typeof(Models.Widget)
};
SearchType = SearchableTypes.First();
}
public ObservableCollection<Type> SearchableTypes { get; }
public ObservableCollection<SearchFieldInfo> Fields { get; }
private Type _searchType;
public Type SearchType
{
get { return _searchType; }
set
{
_searchType = value;
Fields.Clear();
foreach (PropertyInfo prop in _searchType.GetProperties())
{
var searchField = new SearchFieldInfo(prop.Name);
Fields.Add(searchField);
}
}
}
private ICommand _searchCommand;
public ICommand SearchCommand
{
get { return _searchCommand ?? (_searchCommand = new SimpleCommand((obj) =>
{
WindowManager.ShowMessage(String.Join(", ", Fields.Select(f => $"{f.Name}: {f.Value}")));
})); }
}
}
}
的SearchFieldInfo
類:
namespace DynamicViewExample
{
public class SearchFieldInfo
{
public SearchFieldInfo(string name)
{
Name = name;
}
public string Name { get; }
public string Value { get; set; } = "";
}
}
的視圖:
<Window
x:Class="DynamicViewExample.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:DynamicViewExample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="525"
Height="350"
d:DataContext="{d:DesignInstance local:MainWindowVm}"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ComboBox
Grid.Row="0"
ItemsSource="{Binding Path=SearchableTypes}"
SelectedItem="{Binding Path=SearchType}" />
<ItemsControl Grid.Row="1" ItemsSource="{Binding Path=Fields}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
<TextBox Width="300" Text="{Binding Path=Value}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Grid.Row="2" Command="{Binding Path=SearchCommand}">Search</Button>
</Grid>
</Window>
模型類:
class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Id { get; set; }
}
class Widget
{
public string ModelNumber { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
![searching User model](https://i.stack.imgur.com/C5FZj.png)
所以基本上要生成的每個類型T的公共財產一個TextBox? – mm8
@ mm8是的你是對的! – Rahul
我想你知道如何將視圖的DataContext設置爲SearchViewModel? –
mm8