2013-08-26 6 views
1

XML에 일부 컨트롤을 바인딩하는 데 문제가 있습니다.XmlDataProvider에서 바인딩 오류가 발생했습니다 (비 XML 객체에 바인딩 할 수 없음)

class TemplateSelector : DataTemplateSelector 
{ 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
    if (item != null) 
    { 
     string templateFile = string.Format("Templates/{0}", 
              Properties.Settings.Default.AppId + ".tmpl"); 
     if (File.Exists(templateFile)) 
     { 
     FileStream fs = new FileStream(templateFile, FileMode.Open); 
     DataTemplate template = XamlReader.Load(fs) as DataTemplate; 

     Tab tab = item as Tab; 
     XmlDataProvider xmlDataProvider = template.Resources["dataProvider"] as XmlDataProvider; 
     xmlDataProvider.XPath = tab.BridgeObj.XmlFilePath; 

     return template; 
     } 
    } 
    return null; 
    } 
} 

XAML :

<DataTemplate 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:EurocomCPS;assembly=EurocomCPS"> 

    <DataTemplate.Resources> 
    <local:StringToBoolConverter x:Key="StrToBoolConverter" /> 
    <local:StringToIntConverter x:Key="StrToIntConverter" /> 
    <XmlDataProvider x:Key="dataProvider" XPath="func/parametri/param/BLOCKS"/> 
    </DataTemplate.Resources> 

    <Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="100" /> 
     <ColumnDefinition Width="Auto" /> 
    </Grid.ColumnDefinitions> 

    <Label Grid.Row="0" Grid.Column="0" Content="ITEM 1:"/> 
    <Label Grid.Row="1" Grid.Column="0" Content="ITEM 2:"/> 
    <Label Grid.Row="2" Grid.Column="0" Content="ITEM 3:"/> 

    <TextBox Name="TextBox1" 
       Grid.Row="0" 
       Grid.Column="1" 
       Text="{Binding XPath='//BLOCK[@id=1]/ITEMS/ITEM[@id=1]/@value'}" /> 
    <CheckBox Grid.Row="1" 
       Grid.Column="1" 
       IsChecked="{Binding XPath='//BLOCK[@id=1]/ITEMS/ITEM[@id=2]/@value', 
          Converter={StaticResource StrToBoolConverter}}"/> 

    <CheckBox Grid.Row="2" 
       Grid.Column="1" 
       IsChecked="{Binding XPath='//BLOCK[@id=1]/ITEMS/ITEM[@id=3]/@value', 
          Converter={StaticResource StrToBoolConverter}}"/> 

    </Grid> 
</DataTemplate> 

모든 페이지에는 다음 XML 파일을로드 XmlDataProvider를 개최 :


내 응용 프로그램 DataTemplateSelector과 TAB에 대한 XAML을로드, 런타임시에 TabControl을 채 웁니다
<func id="A29086"> 
    <parametri> 
    <param> 
     <BLOCKS max_count="2" write_id="49" read_req_id="47" read_rep_id="48" session_id="7"> 
     <BLOCK id="1" frame="1" framelen="61"> 
      <ITEMS max_count="14"> 
      <ITEM id="1" type="CHAR" size="1" value="0" /> 
      <ITEM id="2" type="CHAR" size="1" value="1" /> 
      <ITEM id="3" type="CHAR" size="1" value="0" /> 
      ... 
      </ITEMS> 
     </BLOCK> 
     <BLOCK id="2" frame="1" framelen="61"> 
      <ITEMS max_count="14"> 
      <ITEM id="1" type="CHAR" size="1" value="0" /> 
      <ITEM id="2" type="CHAR" size="1" value="1" /> 
      ... 
      </ITEMS> 
     </BLOCK> 
     </BLOCKS> 
    </param> 
    </parametri> 
</func> 

이 오류가 발생하면

System.Windows.Data Error: 44 : BindingExpression with XPath cannot bind to non-XML object.; XPath='//BLOCK[@id=1]/ITEMS/ITEM[@id=1]/@value' BindingExpression:Path=/InnerText; DataItem='Tab' (HashCode=57706919); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') Tab:'EurocomCPS.Tab' 
System.Windows.Data Error: 44 : BindingExpression with XPath cannot bind to non-XML object.; XPath='//BLOCK[@id=1]/ITEMS/ITEM[@id=2]/@value' BindingExpression:Path=/InnerText; DataItem='Tab' (HashCode=57706919); target element is 'CheckBox' (Name=''); target property is 'IsChecked' (type 'Nullable`1') Tab:'EurocomCPS.Tab' 
System.Windows.Data Error: 44 : BindingExpression with XPath cannot bind to non-XML object.; XPath='//BLOCK[@id=1]/ITEMS/ITEM[@id=3]/@value' BindingExpression:Path=/InnerText; DataItem='Tab' (HashCode=57706919); target element is 'CheckBox' (Name=''); target property is 'IsChecked' (type 'Nullable`1') Tab:'EurocomCPS.Tab' 

--- 편집 ---

내 컨트롤에 DataContext를 추가하지만, 난 여전히 문제가있다.

System.Windows.Data Error: 44 : BindingExpression with XPath cannot bind to non-XML object.; XPath='//BLOCK[@id=1]/ITEMS/ITEM[@id=1]/@value' BindingExpression:Path=/InnerText; DataItem='Tab' (HashCode=46144604); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') Tab:'EurocomCPS.Tab' 
System.Windows.Data Error: 44 : BindingExpression with XPath cannot bind to non-XML object.; XPath='//BLOCK[@id=1]/ITEMS/ITEM[@id=1]/@value' BindingExpression:Path=/InnerText; DataItem='Tab' (HashCode=46144604); target element is 'TextBox' (Name='TextBox1'); target property is 'Text' (type 'String') Tab:'EurocomCPS.Tab' 

을 그리고 난 아무데도 정의되지 않은 첫 번째 '이름'텍스트 상자에 무엇인지 이해가 안 :
첫 번째 나는 다음과 같은 얻을 수 있다는 것입니다.

두 번째입니다. TextBox 바인딩 (예 : CheckBox에 사용하는 것과 같은)에 변환기를 넣으면 오류가 발생하지 않습니다.

세 번째 변환기 기능이 호출되지 않습니다.

답변

0

내가 Source 어디서나 정의를 참조하지 않는 한, 당신은 어떻게 든 XmlDataProvider에 XML을로드하는 것이 가정 당신의 XPath 괜찮습니다하지만 당신은 바인딩 용으로 Source을 제공하지 않습니다.

<TextBlock Text="{Binding Source={StaticResource dataProvider}, XPath='//BLOCK[@id=1]/ITEMS/ITEM[@id=2]/@value'}"/> 

을 당신이 DataContext에서 찾게됩니다 기본적으로 소스를 지정하지 않을 경우 : 당신이 이런 식으로 변경하면 그것은 작동합니다.

+0

안녕하세요 @ dkozl, 고마워 .. 너 말이 맞아. 내 컨트롤에 DataContext 추가하지만 여전히 몇 가지 문제가 있습니다. 나는 그들을 반영하기 위해 내 대답을 편집 .. – Barzo

0

나는 '@ id = 1'이 blog에 해당하는 올바른 방법이 아니라고 생각합니다.

+0

안녕하세요 @AstiK, 또한 XPath가 유효하다고 확신하는 경우 '@'없이 시도하지만 ID는 더 이상 작동하지 않습니다. – Barzo

0

문제는 XML 파일을 할당하는 방법이었습니다!

xmlDataProvider.XPath = tab.BridgeObj.XmlFilePath; 

xmlDataProvider.Source = new Uri(tab.BridgeObj.XmlFilePath); 

로 변경을 해결했다.