【问题标题】:Setting binding source properly in XAML在 XAML 中正确设置绑定源
【发布时间】:2016-08-24 08:52:23
【问题描述】:

我想要一个 TextBlocks 列表,每个 TextBlocks 旁边都有 ComboBoxes。 每个 ComboBox 的 ComboBoxes 数据源应该相同。然而,每个 TextBlock 都应该包含 List 的后续元素 ComboBoxs 和 TextBlocks 的数据源都在我的“设置”对象中。所以我将整个窗口的DataContext设置为这个设置对象。

这是我的问题: TextBlock的数据源是:List叫做Fields,在一个叫做“Header”的“Line”类型的对象里面(当然是在settings对象里面,就是我的datacontext)。

因此,以图形方式: 设置(类型:设置)-标题(类型:CsvLine)-字段(类型:字符串列表)

现在组合框。每个 ComboBox 的数据源应该是一个名为 Tags 的 List

图形化: 设置(类型:设置)-标签(类型:字符串列表)

我不知道我应该如何指向这些位置,我尝试了很多选项,但都不起作用。我看到的只是一个空白窗口。

这是我的代码:

<Grid>
    <StackPanel Orientation="Horizontal">
        <ItemsControl ItemsSource="{Binding Headers}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Fields}"/>
                        <ComboBox ItemsSource="{Binding DataContext.Tags,
                            RelativeSource={RelativeSource AncestorType=ItemsControl}}">
                        </ComboBox>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</Grid>

我不知道我应该将什么作为 ItemsSource 实际传递给 ItemsControl,因为我认为它应该是 TextBoxes 和 ComboBoxes 的共同来源,但它们唯一的共同来源是设置对象 - 但我已经将它设置为我的 DataContext。 我在 ComboBox 中使用过 RelativeSource,但我不确定它的用途(尽管我在 MSDN 上读过一篇关于它的文章)。我不知道为什么,但我真的很难理解绑定 - 我正在努力让任何东西正常工作。

//编辑: 这是我的设置类 - 这是我的设置对象的类型:

public class Settings
{
    public CsvLine AllHeaders1
    {
        get
        {
            return _allHeaders1;
        }
    }

    public CsvLine _allHeaders1 = new CsvLine()
    {
        Fields = new List<string>()  
        { 
           "Header1" , "Header2" , "Header3" 
        }
    };

    private List<String> _tags;

    public List<String> Tags
    {
        get
        {
            return new List<string>() { "Tag1", "Tag2", "Tag3", "Tag4", "Tag5" };
        }
        set
        {
            _tags = value;
        }
    }

}

这是我的 CsvLine 类:

public class CsvLine
{
    public List<string> Fields = new List<string>();

    public int LineNumber;

}

【问题讨论】:

  • 看起来不像你在一百万英里之外。您能否发布您的设置对象,因为很难从您的描述中提供洞察力?鉴于在您的描述中,字段是字符串列表,因此可以肯定 TextBlock '{Binding Fields}' 中的绑定是错误的。
  • 当然,我一会儿再补充

标签: c# .net wpf xaml binding


【解决方案1】:

所以,我不能 100% 确定您想要什么,但以下内容应该可以帮助您入门。

首先,您需要确保绑定到公共属性——而不是公共成员——因此需要将 CsvLine.Fields 成员更改为 public List&lt;string&gt; Fields { get { return _fields; } set { _fields = value; } }。同样不是这样,如果您希望设置对象中的更改反映在 UI 中,则需要实现 INotifyPropertyChanged。

无论如何,有了这个并分配给网格的 DataContext,下面将显示文本块的垂直列表(显示“标题 1”、“标题 2”、“标题 3”),每个文本块都有一个组合框右侧包含值“Tag1”、“Tag2”...“Tag5”。

<Grid x:Name="SourceGrid">
    <ItemsControl ItemsSource="{Binding Path=AllHeaders1.Fields}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding}" />
                    <ComboBox ItemsSource="{Binding ElementName=SourceGrid, Path=DataContext.Tags}" />
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

希望对你有帮助。

【讨论】:

  • 太棒了,这行得通!你怎么知道它应该如何绑定?我的意思是,你为什么将 ItemsControl 绑定到 AllHeaders.Fields?它是否也适用于组合框,因为它们位于此 ItemsControl 中?如果我在 TextBlock 中直接绑定到 Allheaders1.Fields,为什么它不起作用?
  • TextBlock 只能显示单个内容项并且不需要集合,因此会尝试在它绑定的对象上调用“.ToString()”。我希望,当您将 Allheaders.Fields 集合绑定到 TextBlock 时,它会显示类似“List”的内容(即绑定到 TextBlock 的类的名称)。无论如何,是的,DataContext 也会从 ItemsControl 流入 ComboBox,这就是为什么您需要 ComboBox ItemsSource 的长手绑定,它指定要绑定的元素并专门引用它的 DataContext。
  • 好的,但是如果您将 AllHeaders1.Fields 绑定到 ItemsControl,TextBlock 也会收到该 Bounding,但它不会显示“List” - 它会正确显示此列表的内容。它是怎么做到的?
  • 用简单(而且非常不准确)的术语来说,当您将集合绑定到 ItemsControl.ItemsSource 属性时,ItemsControl 会枚举整个集合,为集合中的每个项目实例化新的 ItemTemplates 并设置 DataContext该 ItemTemplate 到项目本身(不是整个集合)。这就是为什么 TextBox.Text 绑定只是“{Binding}”(即绑定到当前 DataContext,在本例中为字符串)的原因。有意义吗?
  • 是的,很好的解释,现在我明白了。但我仍然不明白为什么 ComboBox 有 Binding ElementName=SourceGrid, Path=DataContext.Tags。您将绑定源设置为窗口中的网格。现在,路径设置为 DataContext.Tags,在本例中是指 SourceGrid.Tags?不,不可能那样,那为什么有ElementName=SourceGrid呢?我以为它是用来绑定到其他控件的,但在这种情况下,我们想绑定到一个名为 Tags 的字符串列表。这种绑定是如何工作的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多