2015-10-06 151 views
2

我有一个列表视图,我将多个数据模板绑定到使用DataTemplateSelector。但是,我无法构建我的项目,我收到“对象引用未设置为对象实例”的错误。我将问题缩小到了组合框的数据绑定ItemsSource。如果我注释掉组合框,我的项目就会建立。据我所知,Binding关键字在运行时进行评估,但这是编译时错误。我尝试通过交换到x:Bind来解决错误,因为它在编译时计算,但是之后需要定义DataTemplate的类型。XAML嵌套模板绑定

x:DataType={x:Type templates:FilterDropdownDataTemplate} 

但是,x:类型未在Windows 10通用应用程序中定义。有什么建议么?

这是我的XAML:

<Page.Resources> 
    <DataTemplate x:Name="DateComboboxTemplate"> 
     <TextBlock Text="{Binding}"/> 
    </DataTemplate> 

    <DataTemplate x:Name="FilterDropdownDataTemplate"> 
     <StackPanel> 
      <TextBlock Text="{Binding Value}"/> 
      <ComboBox ItemsSource="{Binding DateRanges}" 
       SelectionChanged="{Binding DateSelection}" 
       SelectedItem="{Binding SelectedDateRange, Mode=TwoWay}" 
       ItemTemplate="{StaticResource DateComboboxTemplate}"> 
      </ComboBox> 
     </StackPanel> 
    </DataTemplate> 

    <config:MainFilterTemplateSelector 
     x:Name="MainFilterSelector" 
     FilterDropdownTemplate="{StaticResource FilterDropdownDataTemplate}" 
     /> 
</Page.Resources> 

<ListView x:Name="FilterCategories" 
      Margin="0" 
      Padding="0" 
      BorderThickness="0" 
      ItemsSource="{Binding Filters}" 
      SelectedItem="{Binding SelectedFilterCategory, Mode=TwoWay}" 
      IsItemClickEnabled="True" 
      SelectionChanged="{x:Bind ViewModel.OpenSubFilters}" 
      ItemTemplateSelector="{StaticResource MainFilterSelector}"> 
</ListView> 

这里是相关的C#代码(我使用MVVM模式):

public class MainFilterViewDropdownListTemplate : Filter 
{ 
    private ObservableCollection<string> _dateRanges; 
    private string _selectedDateRange; 

    public MainFilterViewDropdownListTemplate() : base() 
    { 
     _dateRanges = new ObservableCollection<string>(); 
    } 

    public ObservableCollection<string> DateRanges 
    { 
     get 
     { 
      return _dateRanges; 
     } 
     set 
     { 
      SetProperty(ref _dateRanges, value); 
      // hard coding these 4 lines for testing for now 
      _dateRanges.Add("Last 7 days"); 
      _dateRanges.Add("Last 14 days"); 
      _dateRanges.Add("Last 30 days"); 
      _dateRanges.Add("Custom"); 
     } 
    } 

    public string SelectedDateRange 
    { 
     get 
     { 
      return _selectedDateRange; 
     } 
     set 
     { 
      SetProperty(ref _selectedDateRange, value); 
     } 
    } 

    public IEnumerable<Filter> AllFilters { get; set; } 

    public void InitializeFields(Filter filter) 
    { 
     Column = filter.Column; 
     DisplayType = filter.DisplayType; 
     ID = filter.ID; 
     IsSelected = filter.IsSelected; 
     ParentId = filter.ParentId; 
     SelectedCount = filter.SelectedCount; 
     TotalCount = filter.TotalCount; 
     Value = filter.Value; 
     visibility = filter.visibility; 
    } 

    private void DateSelection() 
    { 

    } 
} 

而且

public class MainFilterTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate FilterDropdownTemplate { get; set; } 

    protected override DataTemplate SelectTemplateCore(object selector) 
    { 
     if (selector == null) 
     { 
      throw new ArgumentNullException("Template is null"); 
     } 
     if (!(selector is FilterBase)) 
     { 
      throw new ArgumentException("This list can only be populated by a class that extends Filter."); 
     } 
     else 
     { 
      var filterType = selector as Filter; 
      switch (filterType.DisplayType) 
      { 
       case "date": 
        return FilterDropdownTemplate; 
       default: 
        return base.SelectTemplateCore(selector); 
      } 
     } 
    } 
} 

而且

public class Filter : FilterBase 
{ 
    private int _selectedCount; 
    private int _totalCount; 
    private Visibility _visibility; 

    public IEnumerable<Filter> Children 
    { 
     get; 
     set; 
    } 

    public int TotalCount 
    { 
     get 
     { 
      return _totalCount; 
     } 
     set 
     { 
      SetProperty(ref _totalCount, value); 
     } 
    } 

    public int SelectedCount 
    { 
     get 
     { 
      return _selectedCount; 
     } 
     set 
     { 
      SetProperty(ref _selectedCount, value); 
     } 
    } 

    public Visibility visibility 
    { 
     get 
     { 
      return _visibility; 
     } 
     set 
     { 
      SetProperty(ref _visibility, value); 
     } 

    } 

    public void InitializeAllChildren(IEnumerable<Filter> allFilters) 
    { 
     foreach (Filter item in allFilters) 
     { 
      item.Children = allFilters.GetAllChildrenFiltersForParentID(item.ID) as IEnumerable<Filter>; 
      if (item.Children == null) 
      { 
       item.TotalCount = 0; 
      } 
      else 
      { 
       item.TotalCount = item.Children.Count(); 
       item.SelectedCount = item.Children.Where(t => t.IsSelected.Value).Count(); 
      } 
     } 
     Children = allFilters.GetAllChildrenFiltersForParentID(ID); 
    } 
} 

而且

public class FilterBase : ViewModelBase 
{ 
    public int ID 
    { 
     get 
     { 

      return _id; 
     } 
     set 
     { 
      SetProperty(ref _id, value); 
     } 
    } 



    public string Value 
    { 
     get 
     { 
      return _value; 
     } 

     set 
     { 
      SetProperty(ref _value, value); 
     } 
    } 
    public string Column 
    { 
     get 
     { 
      return _column; 
     } 

     set 
     { 
      SetProperty(ref _column, value); 
     } 
    } 

    public int ParentId 
    { 
     get 
     { 
      return _parentId; 
     } 

     set 
     { 
      SetProperty(ref _parentId, value); 
     } 
    } 

    public string DisplayType 
    { 
     get 
     { 
      return _displayType; 
     } 

     set 
     { 
      SetProperty(ref _displayType, value); 
     } 
    } 
    public bool? IsSelected 
    { 
     get 
     { 
      return _isSelected; 
     } 

     set 
     { 
      SetProperty(ref _isSelected, value); 
     } 
    } 

    private int _id; 
    private string _value; 
    private string _column; 
    private int _parentId; 
    private string _displayType; 
    private bool? _isSelected; 
} 

和(BindableBase从Prism.Mvvm命名空间)

public class ViewModelBase : BindableBase, IDisposable 
{ 
    PropertyChangeActionHelper _propertyChangeActionHelper; 

    protected void RegisterPropertyChangeAction(Action action, params string[] monitoredProperties) 
    { 
     if (_propertyChangeActionHelper == null) 
     { 
      _propertyChangeActionHelper = new PropertyChangeActionHelper(this); 
     } 

     _propertyChangeActionHelper.RegisterPropertyChangeAction(action, monitoredProperties); 
    } 

    #region IDisposable Support 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (_propertyChangeActionHelper != null) 
      { 
       _propertyChangeActionHelper.Dispose(); 
       _propertyChangeActionHelper = null; 
      } 
     } 
    } 

    ~ViewModelBase() 
    { 
     // Do not change this code. Put cleanup code in Dispose(bool disposing) above. 
     Dispose(false); 
    } 

    // This code added to correctly implement the disposable pattern. 
    public void Dispose() 
    { 
     // Do not change this code. Put cleanup code in Dispose(bool disposing) above. 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
    #endregion 
} 
+0

它确实是一个构建错误?即一个致命的错误,阻止可执行文件的建立? WPF通常会发出非致命错误,这仅仅是因为编辑器试图评估设计时没有设置的东西。在任何情况下,如果您提供[更好的代码示例](https://stackoverflow.com/help/mcve),您可能会发现您获得答案的运气会更好(例如,您已经省略了两个在XAML),如果您可以使用基本的Windows应用商店应用而不是通用的(并非每个人都已升级到Windows 10兼容的开发环境)来提供repro案例。 –

+0

是的,它阻止了建筑物的代码。我删除了额外的模板并添加了填充列表及其继承树的类。 –

+0

关于'x:Bind'和'x:DataType':假设'templates'命名空间是声明的并且'FilterDropdownDataTemplate'是该命名空间中的一个类型,您应该能够定义DataTemplate的数据类型而不使用'x:Type':'' – andreask

回答

0

假设templates声明命名空间和FilterDropdownDataTemplate是该命名空间中的一个类型,你应该能够使用以下语法定义DataTemplate的数据类型,但不使用x:Type

<DataTemplate x:DataType="templates:FilterDropdownDataTemplate">