![]() |
考研的冰淇淋 · 五种类型男友的礼物合集,特别是30+男人送什 ...· 2 月前 · |
![]() |
小眼睛的大葱 · 图森未来上市首日破发:3年累计收入不足300 ...· 3 月前 · |
![]() |
发财的乌龙茶 · 重返游戏:王者荣耀x三丽鸥家族联动第二弹正式 ...· 5 月前 · |
![]() |
玩篮球的刺猬 · TypeScriptのエラー type ...· 7 月前 · |
![]() |
玩篮球的沙滩裤 · Coomassie Blue Fast ...· 8 月前 · |
我有一个
ListBox
,它绑定到
List
of
DataModel
。
DataModel.cs
public class DataModel
public string Name { get; set; }
public string Desc { get; set; }
public string Code { get; set; }
}
ListBox
应该显示两个属性,因此我已经将
ItemTemplate
定义如下
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"></TextBlock>
<TextBlock Text=" - "></TextBlock>
<TextBlock Text="{Binding Code}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
我的要求是用户可以选择在运行时在
ListBox
中显示哪两个属性。我不知道如何做到这一点。我创建了一个示例解决方案来解释我的问题。
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="5">
<Label Content="Property One"></Label>
<ComboBox Name="ComboBox1" Margin="3" Width="150" ItemsSource="{Binding DataModelProperties}"></ComboBox>
<Label Content="Property Two"></Label>
<ComboBox Name="ComboBox2" Margin="3" Width="150" ItemsSource="{Binding DataModelProperties}"></ComboBox>
<Button Content="Go" Click="ButtonBase_OnClick" Margin="3"></Button>
</StackPanel>
<ListBox Grid.Row="1" ItemsSource="{Binding DataModelList}" Margin="5">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"></TextBlock>
<TextBlock Text=" - "></TextBlock>
<TextBlock Text="{Binding Code}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
namespace WpfApplication1
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
DataContext = new ViewModel();
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
public class ViewModel
public List<String> DataModelProperties { get; set; }
public List<DataModel> DataModelList { get; set; }
public ViewModel()
DataModelList = new List<DataModel>();
DataModelList.Add(new DataModel() { Name = "Name1", Code = "Code1", Desc = "Desc1" });
DataModelList.Add(new DataModel() { Name = "Name2", Code = "Code2", Desc = "Desc2" });
DataModelList.Add(new DataModel() { Name = "Name3", Code = "Code3", Desc = "Desc3" });
DataModelProperties = typeof(DataModel).GetProperties().Select(s => s.Name).ToList();
public class DataModel
public string Name { get; set; }
public string Desc { get; set; }
public string Code { get; set; }
}
我试过的东西
<TextBlock Text="{Binding ElementName=ComboBox1, Path=SelectedItem}"></TextBlock>
这只显示选定的属性名称。
发布于 2015-08-27 13:13:03
简而言之,我所做的是使两个公共属性绑定到并将您的属性更改为字段。此外,我还创建了自定义属性,以控制用户可以选择哪些字段。并创建了一个DisplayOptions类来存储选择,并将其扩展到DataModel实例。考虑到这是一个PoC,解决方案有点混乱,但我相信这可以做到:
XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="5">
<Label Content="Property One"></Label>
<ComboBox Name="ComboBox1" Margin="3" Width="150" ItemsSource="{Binding DataModelProperties}"></ComboBox>
<Label Content="Property Two"></Label>
<ComboBox Name="ComboBox2" Margin="3" Width="150" ItemsSource="{Binding DataModelProperties}"></ComboBox>
<Button Content="Go" Click="ButtonBase_OnClick" Margin="3"></Button>
</StackPanel>
<ListBox Grid.Row="1" ItemsSource="{Binding DataModelList}" Margin="5">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DisplayProperty1}"></TextBlock>
<TextBlock Text=" - "></TextBlock>
<TextBlock Text="{Binding DisplayProperty2}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
政务司司长:
public partial class MainWindow : Window
public ViewModel model = new ViewModel();
public MainWindow()
InitializeComponent();
DataContext = model;
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
//This part has to be on the View side, but this is PoC
model.Opts.Prop1 = typeof(DataModel).GetFields()
.Where(a => a.Name == ComboBox1.SelectedItem.ToString()).FirstOrDefault();
model.Opts.Prop2 = typeof(DataModel).GetFields()
.Where(a => a.Name == ComboBox2.SelectedItem.ToString()).FirstOrDefault();
DataContext = null;
DataContext = model;
public class ViewModel
public DisplayOptions Opts = new DisplayOptions();
public List<String> DataModelProperties { get; set; }
public List<DataModel> DataModelList { get; set; }
public ViewModel()
var properties = typeof(DataModel).GetFields()
.Where(a => a.CustomAttributes.Any(b => b.AttributeType == typeof(SwitchableAttr)));
//Initialising options before creating DataModel instances
DataModelProperties = properties.Select(s => s.Name).ToList();
Opts.Prop1 = properties.ElementAt(0);
Opts.Prop2 = properties.ElementAt(1);
DataModelList = new List<DataModel>();
DataModelList.Add(new DataModel() { Name = "Name1", Code = "Code1", Desc = "Desc1", options = Opts });
DataModelList.Add(new DataModel() { Name = "Name2", Code = "Code2", Desc = "Desc2", options = Opts });
DataModelList.Add(new DataModel() { Name = "Name3", Code = "Code3", Desc = "Desc3", options = Opts });
public class DisplayOptions
public FieldInfo Prop1;
public FieldInfo Prop2;
public class DataModel
public DisplayOptions options;
[SwitchableAttr]
public string Name;
[SwitchableAttr]
public string Desc;
[SwitchableAttr]
public string Code;
public string DisplayProperty1 { get { return (string)options.Prop1.GetValue(this); } set { } }
public string DisplayProperty2 { get { return (string)options.Prop2.GetValue(this); } set { } }
public class SwitchableAttr : Attribute { }
发布于 2015-08-27 13:21:23
我建议您管理与ListBox中ViewModel中显示的“动态描述”有关的所有内容。
首先,视图模型和模型应该实现
INotifyPropertyChanged
。在我的示例中,我创建了一个实现它的简单基类。我的基类名为
NotifyPropertyChangedImpl
。
此外,我在视图模型中添加了两个属性:用于选择属性的组合框绑定到这两个属性。
public class ViewModel : NotifyPropertyChangedImpl
private string property1;
private string property2;
public List<String> DataModelProperties { get; set; }
public List<DataModel> DataModelList { get; set; }
public string Property1
return property1;
if (property1 != value)
property1 = value;
SetDynamicDescriptions();
public string Property2
return property2;
if (property2 != value)
property2 = value;
SetDynamicDescriptions();
public ViewModel()
DataModelList = new List<DataModel>();
DataModelList.Add(new DataModel() { Name = "Name1", Code = "Code1", Desc = "Desc1" });
DataModelList.Add(new DataModel() { Name = "Name2", Code = "Code2", Desc = "Desc2" });
DataModelList.Add(new DataModel() { Name = "Name3", Code = "Code3", Desc = "Desc3" });
DataModelProperties = typeof(DataModel).GetProperties().Select(s => s.Name).ToList();
private void SetDynamicDescriptions()
PropertyInfo propertyInfo1;
PropertyInfo propertyInfo2;
Type type = typeof(DataModel);
if (!String.IsNullOrEmpty(property1) && !String.IsNullOrEmpty(property2))
propertyInfo1 = type.GetProperty(property1);
propertyInfo2 = type.GetProperty(property2);
foreach (DataModel dataModel in DataModelList)
dataModel.DynamicDescription = String.Format("{0} - {1}",
propertyInfo1.GetValue(dataModel, null), propertyInfo2.GetValue(dataModel, null));
}
如您所见,每次
SetDynamicDescriptions
或Property2更改时,Property1都会重新构建Property1。
我还向模型类添加了一个属性:
public class DataModel : NotifyPropertyChangedImpl
private string dynamicDescription;
public string Name { get; set; }
public string Desc { get; set; }
public string Code { get; set; }
public string DynamicDescription
return dynamicDescription;
if (dynamicDescription != value)
dynamicDescription = value;
OnPropertyChanged("DynamicDescription");
}
因此,到最后,您的XAML将是:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="5">
<Label Content="Property One"></Label>
<ComboBox Name="ComboBox1" Margin="3" Width="150" ItemsSource="{Binding DataModelProperties}"
SelectedItem="{Binding Property1}"></ComboBox>
<Label Content="Property Two"></Label>
<ComboBox Name="ComboBox2" Margin="3" Width="150" ItemsSource="{Binding DataModelProperties}"
SelectedItem="{Binding Property2}"></ComboBox>
</StackPanel>
<ListBox Grid.Row="1" ItemsSource="{Binding DataModelList}" Margin="5">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DynamicDescription}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
我希望这能帮到你。
发布于 2015-08-27 13:33:12
这不是完整的MVVM,下面是代码
public partial class MainWindow : Window
private ViewModel vm;
public MainWindow()
InitializeComponent();
vm = new ViewModel();
this.DataContext = vm;
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
if (!string.IsNullOrEmpty(ComboBox1.Text) && !string.IsNullOrEmpty(ComboBox2.Text))
vm.AddDataToModel(ComboBox1.Text, ComboBox2.Text);
public class ViewModel
public List<String> DataModelProperties { get; set; }
private ObservableCollection<DataModel> _DataModelList;
public ViewModel()
_DataModelList = new ObservableCollection<DataModel>();
DataModelProperties = typeof(DataModel).GetProperties().Select(s => s.Name).ToList();
public void AddDataToModel(string cmbx1Val,string cmbx2Val)
_DataModelList.Add(new DataModel() { Name = cmbx1Val, Code = cmbx2Val, Desc = "Desc1" });
public ObservableCollection<DataModel> DataModelList
return _DataModelList;
_DataModelList = value;