Silverlight: привязка к значению LayoutRoot из DataTemplate - PullRequest
2 голосов
/ 06 января 2011

У меня есть DataTemplate для ListBox, где у меня есть несколько элементов управления, которые привязываются к элементу. Я также хотел бы связать со значением на LayoutRoot.DataContext. Я не уверен, как это сделать.

<!--LayoutRoot is the root grid where all page content is placed-->
<StackPanel x:Name="LayoutRoot" Background="Transparent">

    <ListBox ItemsSource="{Binding Items}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding}" />
                    <TextBlock Text="{Binding ElementName=LayoutRoot, Path=DataContext.Foo}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

</StackPanel>

public partial class MainPage : PhoneApplicationPage
{
    public string Foo
    {
        get
        {
            return "the moon";
        }
    }

    private int startIndex = 1;

    private IList<string> _data = new List<string>() { "foo", "bar", "baz" };
    public IList<string> Items
    {
        get
        {
            return _data;
        }
    }

    // Constructor
    public MainPage()
    {
        InitializeComponent();
        LayoutRoot.DataContext = this;
    }
}

Это не работает; отображаются только элементы _data. Следующие ошибки привязки появляются в выходных данных отладки:

System.Windows.Data Error: BindingExpression path error: 'Foo' property not found on 'foo' 'System.String' (HashCode=1502598398). BindingExpression: Path='DataContext.Foo' DataItem='System.Windows.Controls.Border' (HashCode=78299055); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..
System.Windows.Data Error: BindingExpression path error: 'Foo' property not found on 'bar' 'System.String' (HashCode=696029481). BindingExpression: Path='DataContext.Foo' DataItem='System.Windows.Controls.Border' (HashCode=78298703); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..
System.Windows.Data Error: BindingExpression path error: 'Foo' property not found on 'baz' 'System.String' (HashCode=696029489). BindingExpression: Path='DataContext.Foo' DataItem='System.Windows.Controls.Border' (HashCode=78298694); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..

Есть ли где-нибудь синтаксическая ошибка?

Обновление Я стремлюсь к чему-то похожему на это:

  • Foo
  • Луна
  • бар
  • Луна
  • Баз
  • Луна

Вместо этого все, что я получаю, это:

  • Foo
  • бар
  • Баз

(я использую Silverlight для Windows Phone 7.)

Ответы [ 3 ]

2 голосов
/ 06 января 2011

Я не уверен, что вы пытаетесь выполнить, но если вы просто хотите связать свой список с ListBox, вам не нужна эта строка

<TextBlock Text="{Binding ElementName=LayoutRoot, Path=DataContext.Foo}" />

РЕДАКТИРОВАТЬ: (Я только что попробовал это, и это работает)

<ListBox Name="_ViewMapsListBox" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding DataContext.NameName, ElementName=MainGrid}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Codebehind:

private string NameName {get;set;}
void Testing()
{
    NameName = "testing";
    MainGrid.DataContext = this;
}

Возможно, попробуйте установить Foo в вашем основном методе после initialize () ..

РЕДАКТИРОВАТЬ 2: (Хорошо, я только что попробовал это)

<StackPanel x:Name="LayoutRoot" Background="Transparent">

    <ListBox ItemsSource="{Binding Items}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding}" />
                    <TextBlock Text="{Binding ElementName=LayoutRoot, Path=DataContext.Foo}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

</StackPanel>

public partial class MainPage : UserControl
{
    // Constructor
    public MainPage()
    {
        InitializeComponent();
        LayoutRoot.DataContext = this;
    }

    public string Foo
    {
        get
        {
            return "the moon";
        }
    }

    private int startIndex = 1;

    private IList<string> _data = new List<string>() { "foo", "bar", "baz" };
    public IList<string> Items
    {
        get
        {
            return _data;
        }
    }
}

и я получаю вывод как:

Foo Луна бар Луна Baz луна

1 голос
/ 12 мая 2011

Один из вариантов - привязка к ресурсу.

  1. Я переместил свойства Foo и Items в новый класс => SomeClass.
  2. Добавлено пространство имен => xmlns:local="clr-namespace:BindingTest" в UserControl.
  3. Я установилресурс в UserControl => <local:SomeClass x:key="context"/>.
  4. Я связал Layoutroot.DataContext в xaml => DataContext="{Binding Source={StaticResource context}}", хотя вы могли бы сделать это и в коде позади.
  5. Наконец, я привязал textbox.text к ресурсу.Text="{Binding Source={StaticResource context}, Path=Foo}".

    <UserControl.Resources>
        <local:SomeClass x:Key="context" />
    </UserControl.Resources>
    
    <StackPanel x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource context}}">
    
        <ListBox ItemsSource="{Binding Items}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding}" />
                        <TextBlock Text="{Binding Source={StaticResource context}, Path=Foo}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    
    </StackPanel>
    

И код позади:

using System.Collections.Generic;
using Microsoft.Phone.Controls;

namespace BindingTest
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
    }

    public class SomeClass
    {
        private IList<string> _data = new List<string>() { "foo", "bar", "baz" };
        public IList<string> Items
        {
            get
            {
                return _data;
            }
        }

        public string Foo { get { return "the moon"; } }
    }
}
0 голосов
/ 06 января 2011

Я не думаю, что вы можете привязать элемент вне вашего DataTemplate. Вместо этого вам нужно расширить элементы, к которым вы привязываете свой ListBox.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...