【问题标题】:Silverlight: Binding to a LayoutRoot value from within a DataTemplateSilverlight:从 DataTemplate 中绑定到 LayoutRoot 值
【发布时间】:2011-01-06 18:38:17
【问题描述】:

我有一个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 项目。 Debug 输出中出现以下绑定错误:

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')..

我在某处有语法错误吗?

更新我的目标是这样的:

  • 月亮
  • 酒吧
  • 月亮
  • 巴兹
  • 月亮

相反,我得到的只是:

  • 酒吧
  • 巴兹

(我正在为 Windows Phone 7 使用 Silverlight。)

【问题讨论】:

    标签: c# silverlight xaml data-binding windows-phone-7


    【解决方案1】:

    我不确定您要完成什么,但如果您只想将列表绑定到 ListBox,那么您不需要这一行

    &lt;TextBlock Text="{Binding ElementName=LayoutRoot, Path=DataContext.Foo}" /&gt;

    编辑:(我刚试过这个,这个工作)

    <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;
    }
    

    也许,尝试在你的 main 方法中设置 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;
            }
        }
    }
    

    我得到如下输出:

    富 月亮 酒吧 月亮 巴兹 月亮

    【讨论】:

    • 这仍然不起作用。我遇到了和以前一样的绑定错误。
    • @Roasrch:好的,我刚刚注意到PhoneApplicationPage,所以它可能不工作的原因不同。
    • 嗯....我想知道为什么会这样。如何在PhoneApplicationPage 上完成这项工作?
    • 您可以创建一个具有所需属性的对象,并将集合添加为属性。然后将父数据上下文设置为该对象,并将列表框 itemsource 设置为该对象的集合属性。
    【解决方案2】:

    一种选择是绑定到资源。

    1. 我将 Foo 和 Items 属性移到了新的 class=> SomeClass
    2. 在 UserControl 中添加了命名空间 => xmlns:local="clr-namespace:BindingTest"
    3. 我在 UserControl 中设置了一个资源 => &lt;local:SomeClass x:key="context"/&gt;
    4. 我在 xaml => DataContext="{Binding Source={StaticResource context}}" 中绑定了 Layoutroot.DataContext,尽管您也可以在后面的代码中执行此操作。
    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"; } }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我认为您不能绑定到 DataTemplate 之外的元素。相反,您需要展开将 ListBox 绑定到的项目。

      【讨论】:

      • -1:当然,您可以在 DataTemplate 之外绑定元素。您指定属性和 ElementName 来执行此操作。
      猜你喜欢
      • 2013-09-20
      • 2015-01-29
      • 2011-11-22
      • 2013-05-29
      • 2012-08-28
      • 2023-04-05
      • 2021-08-22
      • 2014-07-30
      • 2012-08-11
      相关资源
      最近更新 更多