web-dev-qa-db-ja.com

文字列のリストをWPF / WP7のListBoxにデータバインドするにはどうすればよいですか?

文字列値のリストをリストボックスにバインドして、値が行ごとにリストされるようにしています。今私はこれを使用します:

<ListBox Margin="20" ItemsSource="{Binding Path=PersonNames}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Id}"></TextBlock>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

しかし、Idの代わりに、テキストブロックに何を入れるべきかはわかりません。これらはすべてカスタムクラスではなく、文字列値です。

また、MainPage.PersonNamesのように、MainPage内にPersonNamesがある場合、PersonNamesを見つける必要がないという苦情もあります。

データコンテキストを次のように設定します。

DataContext="{Binding RelativeSource={RelativeSource Self}}"

私はそれを間違っていますか?

61
Joan Venge

ItemsSourceが次のようにバインドされていると単純に言えば:

YourListBox.ItemsSource = new List<String> { "One", "Two", "Three" };

XAMLは次のようになります。

<ListBox Margin="20" Name="YourListBox">
    <ListBox.ItemTemplate> 
        <DataTemplate> 
            <StackPanel Orientation="Horizontal"> 
                <TextBlock Text="{Binding}" /> 
            </StackPanel> 
        </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

更新:

これは、DataContextを使用する場合のソリューションです。次のコードは、ページのDataContextとDataContextの設定に渡すビューモデルです。

public class MyViewModel
{
    public List<String> Items
    {
        get { return new List<String> { "One", "Two", "Three" }; }
    }
}

//This can be done in the Loaded event of the page:
DataContext = new MyViewModel();

XAMLは次のようになります。

<ListBox Margin="20" ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

このアプローチの利点は、MyViewModelクラスにさらに多くのプロパティまたは複雑なオブジェクトを配置し、XAMLに抽出できることです。たとえば、Personオブジェクトのリストを渡すには:

public class ViewModel
{
    public List<Person> Items
    {
        get
        {
            return new List<Person>
            {
                new Person { Name = "P1", Age = 1 },
                new Person { Name = "P2", Age = 2 }
            };
        }
    }
}

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

XAML:

<ListBox Margin="20" ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Name}" />
                <TextBlock Text="{Binding Path=Age}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

お役に立てれば! :)

133
Abbas

PersonNamesのコードを表示する必要がありますが、あなたの質問は理解できませんが、次のようにバインドしたい場合があります。

<TextBlock Text="{Binding Path=.}"/>

または

<TextBlock Text="{Binding"} />

これにより、リスト内の現在の要素にバインドされます。 (PersonNamesが文字列のリストであると仮定します)。それ以外の場合、リストにクラス名が表示されます

16
mindandmedia

アイテムのソースが文字列エントリとして列挙可能な場合、次を使用します。

<TextBlock Text="{Binding}"></TextBlock> 

この構文は任意のオブジェクトで使用できます。通常、ToString()メソッドは、値を取得するために呼び出されます。多くの場合、これは非常に便利です。ただし、変更通知は行われないことに注意してください。

9
HCL

これを行うには、TextBlockコントロールをListBoxの一部として明示的に定義する必要はありません(より適切な書式設定が必要な場合を除く)。バインディングをトリガーするためのトリックは、ObservableCollection<string>の代わりにList<string>を使用することです

Window1.xaml

<ListView Width="250" Height="50" ItemsSource="{Binding MyListViewBinding}"/>

Window1.xaml.cs

public Window1()
{
   InitializeComponent();
   DataContext = this;

   // Need to initialize this, otherwise you get a null exception
   MyListViewBinding = new ObservableCollection<string>();
}

public ObservableCollection<string> MyListViewBinding { get; set; }

// Add an item to the list        
private void Button_Click_Add(object sender, RoutedEventArgs e)
{
   // Custom control for entering a single string
   SingleEntryDialog _Dlg = new SingleEntryDialog();

   // OutputBox is a string property of the custom control
   if ((bool)_Dlg.ShowDialog())
      MyListViewBinding.Add(_Dlg.OutputBox.Trim());
}
2
Kevin K