2017-08-17 93 views
1

这是我第一次构建UWP应用程序,并且我一般都是C#/ Windows的新手。我正尝试在用户界面中使用透视。我希望枢轴标题来自连接的usb设备的ObservableCollection,其类别为Device_Info。每个USB设备都有一个名为HardwareRevNumMajor的属性,我希望将其显示为每个支点标题。我的XAML看起来像这样:uwp xaml DataBinding ObservableCollection内部的嵌套属性

<Page 
x:Class="usb_test.MainPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="using:usb_test" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:code="using:usb_test" 
mc:Ignorable="d"> 
<Page.DataContext> 
    <local:View_Model/> 
</Page.DataContext> 

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <Pivot x:Name="pivot1" Title="Pivot" Opacity="0.99" ItemsSource="{Binding Devices}"> 
     <Pivot.HeaderTemplate> 
      <DataTemplate> 
       <TextBlock> 
        <TextBlock.Text> 
         <Binding Path="Device_Info.HardwareRevNumMajor"/> 
        </TextBlock.Text> 
       </TextBlock> 

       <!--<TextBlock Text="{Binding HardwareRevNumMajor}"> 
       </TextBlock>--> 
      </DataTemplate> 
     </Pivot.HeaderTemplate> 
     <Pivot.ItemTemplate> 
      <DataTemplate> 
       <ItemsControl ItemsSource="{Binding DeviceFiles}"> 
        <ItemsControl.ItemTemplate> 
         <DataTemplate> 
          <StackPanel Orientation="Horizontal"> 
           <TextBlock Text="{Binding numBlocks}"/> 
           <TextBlock Text="{Binding syncTime}"/> 
          </StackPanel> 
         </DataTemplate> 
        </ItemsControl.ItemTemplate> 
       </ItemsControl> 
      </DataTemplate> 
     </Pivot.ItemTemplate> 
    </Pivot> 
</Grid> 

只要一个Device_Info对象被添加到Devices的ObservableCollection我得到一个错误。 Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))。然后,如果我点击我的MainPage.xaml中文件中的设计师,我看到:

TargetException: Object does not match target type. 
StackTrace: 
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target) 
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, 
BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) 
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index) 
InnerException: None 

你可以从上面的XAML我已经尝试了多种方式来显示HarwareRevNumMajor属性,住在一个Device_Info见由注释掉的TextBlock代码。

我的视图模型是这样的:

namespace usb_test 
{ 
    public class View_Model 
    { 
     public ObservableCollection<Device_Info> _devices; 
     public ObservableCollection<File_Info> _deviceFiles; 
     public CoreDispatcher _dispatcher; 
    public View_Model() { 
     _devices = new ObservableCollection<Device_Info>(); 
     _deviceFiles = new ObservableCollection<File_Info>(); 
    } 

    public ObservableCollection<Device_Info> Devices 
    { 
     get 
     { 
      return _devices; 
     } 
    } 

    public ObservableCollection<File_Info> DeviceFiles 
    { 
     get 
     { 
      return _deviceFiles; 
     } 
    } 

在我MainPage.xaml.cs中我有这样的:

namespace usb_test 
{ 
    public sealed partial class MainPage : Page 
    { 
    Device_List devList = new Device_List(); 
    Device_Structure deviceStruct = new Device_Structure(); 
    View_Model viewModel = new View_Model(); 
    public MainPage() 
    { 
     this.InitializeComponent(); 
     viewModel._dispatcher = Dispatcher; 
     this.DataContext = viewModel; 
     devList.devices.CollectionChanged += this.OnCollectionChanged; 
     deviceStruct.deviceFiles.CollectionChanged += this.OnCollectionChanged; 
... 

这行代码是用来添加一个设备到列表:

await viewModel._dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => { devList.devices.Add(devInfo); }); 

该行成功并将Dev_Info对象添加到设备observableCollection和shor在应用程序崩溃之后。

我敢肯定,当我尝试在xaml中稍后显示文件信息的东西时会出现更多错误,但是我真的很感谢只是让pivot header正确显示。就像我说的,我对这个很陌生,所以我假设存在一些问题,我会很感激任何建议/澄清什么阻止了我无法显示Dev_Info对象的属性。

谢谢!

+0

'灾难性故障'是xaml框架中相当普遍的错误。隔离各个组件以试图找出失败的原因。您能否将''成功绑定到可观察集合之外的单个Device_Info?如果您注释掉HeaderTemplate,上述xaml是否工作?如果你注释掉ItemTemplate?都? –

回答

0

Devices您的项目是Device_Info类型。在您的DataTemplate中,您将文本属性绑定到Device_Info.HardwareRevNumMajor。由于上下文是您的项目(Device_Info),因此您尝试访问属性Device_Info。

如果你写:

<TextBlock Text="{Binding HardwareRevNumMajor}" /> 

您尝试访问属性HardwareRevNumMajor至极可能存在于DEVICE_INFO。

+0

感谢您的回复。上面我指出我也试过这个:'<! - - >'那也没用。还有其他建议吗? – fgv

+0

你可以测试'Text =“{Binding}”'来检查你的上下文是什么。 –

0

感谢您的上述建议。我取得了一些进展。

我改写了我的XAML这样的:

<Page 
x:Class="usb_test.MainPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="using:usb_test" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:code="using:usb_test" 
mc:Ignorable="d"> 

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <Pivot x:Name="pivot1" Title="Pivot" Opacity="0.99" ItemsSource="{x:Bind viewModel.Devices}"> 
     <Pivot.HeaderTemplate> 
      <DataTemplate x:DataType="local:Device_Info"> 
       <TextBlock Text="{x:Bind HardwareRevNumMajor}"></TextBlock> 
      </DataTemplate> 
     </Pivot.HeaderTemplate> 
     <Pivot.ItemTemplate> 
      <DataTemplate x:DataType="local:Device_Info"> 
       <ListView ItemsSource="{x:Bind devStruct.deviceFiles}" Grid.Row="1"> 
        <ListView.ItemTemplate> 
         <DataTemplate x:DataType="local:File_Info"> 
          <StackPanel Orientation="Horizontal"> 
           <TextBlock Foreground="Red" Text="{x:Bind fileName}" HorizontalAlignment="Center" Margin="0,0,20,0"/> 
           <TextBlock Foreground="Red" Text="{x:Bind numBlocks}" HorizontalAlignment="Center" Margin="0,0,20,0"/> 
           <Button Content="Download File" Click="{x:Bind onDownloadClick}" HorizontalAlignment="Center" Margin="0,0,20,0"> 
           </Button> 
          </StackPanel> 
         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 
      </DataTemplate> 
     </Pivot.ItemTemplate> 
    </Pivot> 
</Grid> 

你会发现,我从我以前的XAML代码拿出

<Page.DataContext> 
    <local:View_Model/> 
</Page.DataContext> 

然后我在Pivot中使用了ItemsSource="{x:Bind viewModel.Devices}">viewModel在我的MainPage.xaml.cs中定义,并且是我在上面创建的View_Model类的一个实例。然后从那里我添加DataTypeDataTemplate这是一个Device_Info然后我可以很容易地访问Device_Info对象的属性,在这种情况下HardwareRevNumMajor

PivotItemTemplate有点混乱。类Device_Info上有一个属性,名为devStruct,它是我创建的类(Device_Struct)。 Device_Struct的实例具有File_Info对象的ObservableCollection。所以这个集合告诉我们设备上的文件,它被称为deviceFiles。这是我想在数据透视项目中使用的集合。我不确定是否有一种方法可以在不插入到XAML的情况下做到这一点,但这是我发现的作品。有了这个,我现在可以显示有关每个数据透视表项上的文件的信息。

我也从使用Binding切换到x:Binding。说实话,我不确定为什么这会有所帮助,但是当我使用Binding时,我得到了:Object reference not set to an instance of an object。如果任何人有更好的理解,我很乐意听到它。再次感谢!