在WPF中的代码隐藏中为ListBox创建ItemTemplate-第二部分 [英] Create ItemTemplate for ListBox in code-behind in WPF - Part II

查看:62
本文介绍了在WPF中的代码隐藏中为ListBox创建ItemTemplate-第二部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在第二部分中提到了这个问题,因为我已经在这里

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆