在WPF中的代码隐藏中为ListBox创建ItemTemplate-第二部分 [英] Create ItemTemplate for ListBox in code-behind in WPF - Part II
问题描述
I named this question of mine Part II since I've already asked a similar but simpler question about creating an ItemTemplat for ListBox in WPF in here Create ItemTemplate for ListBox in code-beind in WPF
现在我要扩大我的问题.我想要一个用于ListBox的ItemTemplate,以便可以在绑定或不绑定到ObservableCollection的情况下使用它.
Now I'm going to expand my question. I want to have an ItemTemplate for a ListBox so that it can be used either with or without binding to an ObservableCollection.
如果我不想将ItemsSource绑定到ObservableCollection,请使用以下代码:
If I don't want to bind the ItemsSource to an ObservableCollection I use the code as follows:
var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));
textBlockFactory.SetValue(TextBlock.TextProperty, new Binding(".")); // Here
textBlockFactory.SetValue(TextBlock.BackgroundProperty, Brushes.Red);
textBlockFactory.SetValue(TextBlock.ForegroundProperty, Brushes.Wheat);
textBlockFactory.SetValue(TextBlock.FontSizeProperty, 18.0);
var template = new DataTemplate();
template.VisualTree = textBlockFactory;
MyListBox.ItemTemplate = template;
但是,对于ItemSource绑定到ObservableCollection而言,它不起作用,因为TextBlock.TextProperty必须绑定到DisplayMemberPath属性.
But it doesn't work for ItemsSource binding to an ObservableCollection since the TextBlock.TextProperty must binds to the DisplayMemberPath property.
对不起,语法错误.
推荐答案
首先,您需要创建一个变量来确定状态:正在使用集合,还是仅使用字符串数组.此标志也可以是依赖项属性,在我的示例中为SomeFlag
:
First of all you need to create a variable that will determine the state: are using a collection, or just an array of strings. This flag can also be a dependency property, in my example it's a SomeFlag
:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
bool SomeFlag = false;
if (SomeFlag == false)
{
var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));
textBlockFactory.SetValue(TextBlock.TextProperty, new Binding("."));
textBlockFactory.SetValue(TextBlock.BackgroundProperty, Brushes.Red);
textBlockFactory.SetValue(TextBlock.ForegroundProperty, Brushes.Wheat);
textBlockFactory.SetValue(TextBlock.FontSizeProperty, 18.0);
var template = new DataTemplate();
template.VisualTree = textBlockFactory;
MyListBox.ItemTemplate = template;
}
else
{
MyListBox.DisplayMemberPath = "Name";
MyListBox.SelectedValuePath = "Age";
}
}
要进行测试,请添加以下SelectionChanged
事件的处理程序:
And for testing, add this handler of SelectionChanged
event:
private void MyListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("SelectedValue is " + MyListBox.SelectedValue);
}
下面是一个完整的示例:
Below is a full example:
XAML
<Grid>
<ListBox Name="MyListBox"
SelectionChanged="MyListBox_SelectionChanged"
ItemsSource="{Binding Path=MyCollection}" />
</Grid>
Code-behind
public partial class MainWindow : Window
{
ViewModel MyViewModel = new ViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = MyViewModel;
MyViewModel.MyCollection = new ObservableCollection<Person>();
MyViewModel.MyCollection.Add(new Person()
{
Age = 22,
Name = "Nick",
});
MyViewModel.MyCollection.Add(new Person()
{
Age = 11,
Name = "Sam",
});
MyViewModel.MyCollection.Add(new Person()
{
Name = "Kate",
Age = 15,
});
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
bool SomeFlag = false;
if (SomeFlag == false)
{
var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));
textBlockFactory.SetValue(TextBlock.TextProperty, new Binding("."));
textBlockFactory.SetValue(TextBlock.BackgroundProperty, Brushes.Red);
textBlockFactory.SetValue(TextBlock.ForegroundProperty, Brushes.Wheat);
textBlockFactory.SetValue(TextBlock.FontSizeProperty, 18.0);
var template = new DataTemplate();
template.VisualTree = textBlockFactory;
MyListBox.ItemTemplate = template;
}
else
{
MyListBox.DisplayMemberPath = "Name";
MyListBox.SelectedValuePath = "Age";
}
}
private void MyListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("SelectedValue is " + MyListBox.SelectedValue);
}
}
public class ViewModel : NotificationObject
{
#region MyCollection
public ObservableCollection<Person> MyCollection
{
get;
set;
}
#endregion
}
#region Model
public class Person
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
#endregion
#region NotificationObject
public class NotificationObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
#endregion
这篇关于在WPF中的代码隐藏中为ListBox创建ItemTemplate-第二部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!