4


1

WPFでは、DataTemplateのTextblockのテキストバインディングをコードで変更する方法は?

ItemsSourceがオブジェクトのリストにバインドされているListBoxがあります。 リストボックスには、TextBlockを含むDataTemplateを持つItemTemplateがあります。 テキストブロックのテキストは、オブジェクトのNameプロパティにバインドされます(つまり、 Text = "\ {Binding Name}")。

同じリストの異なるビューを表示するラジオボタンを提供したいと思います。 たとえば、ユーザーはNameプロパティとIDプロパティを切り替えることができます。

私はこれに対するSOの答えをhttps://stackoverflow.com/questions/2381740/changing-datatemplate-textblock-property-at-runtime[2381740]で見つけましたが、データテンプレートに境界線とテキストボックススタイルセットもあります(コードを参照)以下)。

とにかくTextblockバインディングをリセットするだけですか? datatemplate全体を再作成する必要はありません。 実際、どうすればいいのかわかりませんが、xamlをコードに変換する簡単な方法はありますか?

ありがとうコーディ


3 Answer


13


Wallstreet Programmerのソリューションは、ラジオボタンを使用しているため、うまく機能します。 しかし、この質問の今後の読者のために言及すべきだと思った、より一般的な解決策があります。

DataTemplateを変更して、プレーンな「\ {Binding}」を使用できます。


次に、コードで完全なDataTemplateを再作成する必要はありません。 あなたがしなければならないのはこれを再作成することです:


簡単です:

private DataTemplate GeneratePropertyBoundTemplate(string property, string templateKey)
{
  var template = FindResource(templateKey);
  FrameworkElementFactory factory = new FrameworkElementFactory(typeof(ContentPresenter));
  factory.SetValue(ContentPresenter.ContentTemplateProperty, template);
  factory.SetBinding(ContentPresenter.ContentProperty, new Binding(property));
  return new DataTemplate { VisualTree = factory };
}

これは、ラジオボタンの例でも、多くのプロパティがある場合に特に便利です。


7


自分で簡単にして、2つのテキストブロックを使用して、そのうちの1つを非表示にしてください。

XAML:


コードビハインド:

using System.Collections.Generic;
using System.Windows;

namespace Test
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            DataContext = this;
        }

        public IEnumerable Items
        {
            get
            {
                return new List() {"Bob", "Sally", "Anna"};
            }
        }
    }
}


2


値コンバーターを使用して、データオブジェクトのプロパティを選択することもできます。 個々のプロパティではなく、オブジェクト全体にバインドする必要があります。 データオブジェクトがINotifyPropertyChangedを実装している場合、このソリューションは機能しません。

XAML


コードビハインド:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace Test
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            _propertyPickerConverter = FindResource("PropertyPickerConverter") as PropertyPickerConverter;
            _propertyPickerConverter.PropertyName = "Name";

            DataContext = this;
        }

        public IEnumerable Items
        {
            get
            {
                return new List() {"Bob", "Sally", "Anna"};
            }
        }

        private void OnRadioButtonClick(object sender, RoutedEventArgs e)
        {
            _propertyPickerConverter.PropertyName = (sender as RadioButton).Content as string;

            _listBox.Items.Refresh();
        }

        private PropertyPickerConverter _propertyPickerConverter;
    }

    public class PropertyPickerConverter : IValueConverter
    {
        public string PropertyName { get; set; }

        #region IValueConverter Members
        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string item = value as string;
            switch (PropertyName)
            {
                case "Name": return item;
                case "Length": return item.Length;
                default: return null;
            }
        }

        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new System.NotImplementedException();
        }
        #endregion
    }
}