【问题标题】:Binding XmlElement from DataContext into control将 DataContext 中的 XmlElement 绑定到控件中
【发布时间】:2016-11-02 15:57:56
【问题描述】:

我的问题是接收具有 1 个 XmlElement 的 DataContext,并将其传递给转换器。转换器需要完整的元素,因为它使用多个属性。问题是它接收 MS.Internal.data.xmldatacollection,其中包含一个 XmlElement,我不知道如何继续。

<UserControl x:Class="W3.Views.ComboView" ...>
    <ComboBox Style="{StaticResource ComboButtonStyle}" Width="auto" Height="auto"
         Text="{Binding XPath=.,
                        Converter={StaticResource valueFormattingConverter }}"                IsEditable="True" />
</UserControl>

转换器类:

[ValueConversion(typeof(XmlElement), typeof(string))]
public class ValueFormattingConverter : IValueConverter
{

public object Convert(object val, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
  if (targetType != typeof(string))
    throw new InvalidOperationException("The target must be a List<string>");
  if (val == null) return new List<string>();
  XmlElement e = null;

  if (val is string ) e = val as XmlElement;
  if (e == null) return null;

  return Information.XmlAccess.FormatXmlField(e);
}

因此,这里的 val 作为 MS.Internal.data.xmldatacollection 接收,我不知道如何处理它以获取它包含的 XmlElement。

获取数据的重要上下文: 全部的

如果我们可以修复它,那么修复也需要在这个更复杂的环境中发挥作用:

<ContentControl x:Class="W3.Views.SimpleControlChooser"   >
    <ContentControl.Resources>
        <DataTemplate x:Key="combo" >
            <W3V:ComboView />
        </DataTemplate>
   // skipping other templates
    </ContentControl.Resources>
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <Setter Property="ContentTemplate" Value="{StaticResource combo}" />

            <Style.Triggers>
                <DataTrigger Binding="{Binding XPath=@format}" Value="check">
                    <Setter Property="ContentTemplate" Value="{StaticResource check}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding XPath=@format}" Value="combo">
                    <Setter Property="ContentTemplate" Value="{StaticResource combo}" />
                </DataTrigger>

        //// skipping other DataTriggers

            </Style.Triggers>
        </Style>

    </ContentControl.Style>
</ContentControl>

对,那么数据在哪里指定?上一级:

<UserControl x:Class="W3.Views.SimpleControl" ...>
     ...
  <W3V:ControlLabel x:Name="Label"  FontSize="12"                     
                    Width="{Binding LabelWidth,
                    RelativeSource={RelativeSourceAncestorType=W3V:SimpleControl}}" />

     <W3V:SimpleControlChooser Content="{Binding}" />

我真的不明白 Content=line。

<ItemsControl  ItemsSource="{Binding XPath=*}" Margin="0,0,0,0">
  <ItemsControl.ItemTemplate>
    <DataTemplate>

      <W3V:SimpleControl x:Name="simple"  Content="{Binding}" 
            LabelWidth="{Binding LabelWidth,
                         RelativeSource={RelativeSource AncestorType=W3V:PropertyView}}" />


    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

这种用法目前有效,我不想破坏这个来让另一个工作。如果需要不同,我愿意在 Convert() 方法中编写条件代码以适应数据。

【问题讨论】:

    标签: c# xml wpf data-binding


    【解决方案1】:

    问题与数据绑定有关,与值转换器无关。

    您的数据绑定假定ComboBox.DataContext 引用的对象是一个 XmlElement 实例。但事实并非如此,正如您所说,数据上下文 具有 类型为 XmlElement 属性的属性。

    这是事情变得有点棘手的时候。在绑定中同时指定PathXPath 是行不通的,因为XPath is evaluated first。一个有效的解决方法是将组合框的数据上下文绑定到 XmlElement 本身:

    <ComboBox
        DataContext="{Binding MyXmlElement}"
        Text="{Binding XPath=@value}" />
    

    顺便说一句,一旦数据绑定正确,就不需要转换器来获取组合框中显示的value属性的值。

    2016 年 3 月 11 日编辑

    如果组合框的父项的数据上下文是 XmlElement 实例的数组而不是单个实例,则您始终可以使用索引运算符在绑定中指向正确的元素:

    <ComboBox
        DataContext="{Binding MyXmlElement[0]}"
        Text="{Binding XPath=@value}" />
    

    现在,如果您仍然需要绑定到 XML 元素(实际上是 XmlNode)而不是其属性之一,那么您可以这样做并使用转换器:

    <ComboBox
        DataContext="{Binding MyXmlElement[0]}"
        Text="{Binding XPath=., Converter={StaticResource ValueFormattingConverter}}" />
    

    但是您需要修复当前的转换器,因为它声明了从 XmlElementstring 的转换,而是返回一个 List&lt;string&gt; 实例。

    简而言之,因为XPathPath 之前被评估,所以您不能在ComboBox.Text 数据绑定中同时使用这两者。一个有效的解决方法是将ComboBox.DataContext 绑定到感兴趣的XmlElement,然后在ComboBox.Text 绑定中仅指定XPath

    【讨论】:

    • 我无法使用 Binding XPath=@value,因为我需要完整的 XmlElement。编辑:我的错误,我发布了错误的代码,因为我正在试验。改回 XPath=。 ~~~~~ 我不能使用 DataContext="{Binding MyXmlElement}" 因为 MyXmlElement 不是成员变量,而是这个类接收数组中的元素作为它的数据上下文。
    • 您能发布您班级数据上下文的代码吗?
    • 这很复杂,因为它是一个对相同数据进行操作的复合控件,但没关系。
    • 添加了详细信息。我警告过这很复杂!
    • @AlanBaljeu 别管它有多复杂,只要你知道ComboBox 的继承数据上下文是什么,你就可以通过显式绑定来改进它并解决来自的问题XPathPath 之前被评估。
    猜你喜欢
    • 1970-01-01
    • 2015-09-22
    • 2023-04-10
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多