2013-05-15 43 views
0

我有實體WPF樹視圖,從數據庫表默認建立其引用本身自referensed實體使用綁定轉換器和的ObservableCollection

我是新來的,低信譽不alows我添加圖像,所以我會盡我所能寫。

地區:EntityObject

屬性:

ID

ParentArea_ID

導航屬性:

區 - 一個區域,區域的集合

ParentArea - 以區instanse

我想用數據庫表中的數據填充樹視圖。我發現了2個選項:使用來自here的包裝或綁定轉換器。我是初學者,可能是錯誤的,但它使用綁定轉換器與我聯繫是更好的方法。

我發現我必須做與地區收集了一類新作導航easyer執行,添加,刪除

class AreasCollection:ObservableCollection<Area> 
{ 
    private DBEntities _context; 

    public DBEntities Context 
    { 
     get { return _context; } 
    } 

    public AreasCollection(IEnumerable<Area> Areas, DBEntities context) 
     : base(Areas) 
    { 
     _context = context; 
     foreach (Area a in Areas) 
     { 
      a.Areas.AssociationChanged +=new CollectionChangeEventHandler(Areas_AssociationChanged); 
     } 
    } 

    void Areas_AssociationChanged(object sender, CollectionChangeEventArgs e) 
    { 
     if (e.Action == CollectionChangeAction.Remove) 
     { 
      this.Context.DeleteObject((Area)e.Element); 
      this.Context.DeleteObject((SpareDevice)e.Element); 
      this.Context.DeleteObject((AreaDevice)e.Element); 
      this.Context.DeleteObject((Executor)e.Element); 
     } 
    } 

    protected override void InsertItem(int index, Area item) 
    { 
     item.Areas.AssociationChanged += new CollectionChangeEventHandler(Areas_AssociationChanged); 
     this.Context.AddToAreas(item); 
     base.InsertItem(index, item); 
    } 

    protected override void RemoveItem(int index) 
    { 
     Area a = this[index]; 
     a.Areas.AssociationChanged -= Areas_AssociationChanged; 
     for (int i = a.Areas.Count - 1; i >= 0; i--) 
     { 
      this.Context.DeleteObject(a.Areas.ElementAt(i)); 
     } 
     for (int i = a.SpareDevices.Count - 1; i >= 0; i--) 
     { 
      this.Context.DeleteObject(a.SpareDevices.ElementAt(i)); 
     } 
     for (int i = a.AreaDevices.Count - 1; i >= 0; i--) 
     { 
      this.Context.DeleteObject(a.AreaDevices.ElementAt(i)); 
     } 
     for (int i = a.Executors.Count - 1; i >= 0; i--) 
     { 
      this.Context.DeleteObject(a.Executors.ElementAt(i)); 
     } 
     this.Context.DeleteObject(this[index]); 
     base.RemoveItem(index); 
    } 
} 

而且我發現我必須做一個新的轉換器類

public class AreasConverter : IValueConverter 
{ 
    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     var item = value as Area; 
     return item.Areas.Where(a => a.ParentArea_ID == item.ID); 
    } 

    public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

我的XAML:

<TreeView Name="AreasTreeView" Height="350" ItemsSource="{Binding Converter={StaticResource AreasConverter}}" ItemTemplate="{StaticResource ItemTemplate}"> 
    <TreeView.Resources> 
     <local:AreasConverter x:Key="AreasConverter"/> 
     <HierarchicalDataTemplate x:Key="ItemTemplate" ItemsSource="{Binding Converter={StaticResource AreasConverter}}"> 
      <TextBlock Text="{Binding Path=ShortName}" /> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
    </TreeView> 

而且XAML.cs

public partial class MainWindow : Window 
{ 
    private DBEntities context = new DBEntities(); 
    private CollectionViewSource AreasConverterViewSourse; 
    private ListCollectionView AreasConverter; 


    public MainWindow() 
    { 
     InitializeComponent(); 
     AreasTreeView.ItemsSource = context.Areas.Where(a => a.ParentArea_ID == null); 
     AreasConverterViewSourse = (CollectionViewSource)FindResource("AreasConverter"); 
     this.AreasConverter = (ListCollectionView)this.AreasConverterViewSourse.View; 

    } 
} 

因爲它是我有一個錯誤資源「ItemTemplate」無法解析。

如果我刪除的ItemTemplate = 「{StaticResource的ItemTemplate中}」

<TreeView Name="AreasTreeView" Height="350" ItemsSource="{Binding Converter={StaticResource AreasConverter}}" ItemTemplate="{StaticResource ItemTemplate}"> 

錯誤消失,但是當我嘗試運行應用程序exeption發生

System.Windows.Markup.XamlParseException occurred 
    HResult=-2146233087 
    Message='Provide value on 'System.Windows.StaticResourceExtension' threw an exception.' Line number '30' and line position '61'. 
    Source=PresentationFramework 
    LineNumber=30 
    LinePosition=61 
    StackTrace: 
     at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri) 
     at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri) 
     at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream) 
     at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator) 
     at Maintenance.MainWindow.InitializeComponent() in c:\DATA\Maintenance\Maintenance\MainWindow.xaml:line 1 
     at Maintenance.MainWindow..ctor() in c:\DATA\Maintenance\Maintenance\MainWindow.xaml.cs:line 44 
    InnerException: 
     HResult=-2146233088 
     Message=Cannot find resource named 'AreasConverter'. Resource names are case sensitive. 
     Source=PresentationFramework 
     StackTrace: 
      at System.Windows.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider) 
      at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider) 
     InnerException: 

這是我的第一個wpf應用程序和第一個數據庫設計(16個表格)。從這個項目開始,我已經花了6個弱點開始使用sql server和wpf視頻,Google時間和日期。我的大腦開始沸騰。如果答案儘可能詳細,我會表示贊同。

感謝您的幫助!

回答

2

下面

XAML的工作溶液:

<Window.Resources> 
     <local:AreasConverter x:Key="AreasConverter"/> 
    </Window.Resources> 


      <TreeView Name="AreasTreeView" Height="350"> 
       <TreeView.ItemTemplate> 
        <HierarchicalDataTemplate ItemsSource="{Binding Converter={StaticResource AreasConverter}}"> 
         <TextBlock Text="{Binding Path=ShortName}" /> 
        </HierarchicalDataTemplate> 
       </TreeView.ItemTemplate> 
      </TreeView> 

的ObservableCollection CS:

class AreasCollection:ObservableCollection<Area> 
{ 
    private DBEntities _context; 

    public DBEntities Context 
    { 
     get { return _context; } 
    } 

    public AreasCollection(IEnumerable<Area> Areas, DBEntities context) 
     : base(Areas) 
    { 
     _context = context; 
     foreach (Area a in Areas) 
     { 
      a.Areas.AssociationChanged +=new CollectionChangeEventHandler(Areas_AssociationChanged); 
     } 
    } 

    void Areas_AssociationChanged(object sender, CollectionChangeEventArgs e) 
    { 
     if (e.Action == CollectionChangeAction.Remove) 
     { 
      this.Context.DeleteObject((Area)e.Element); 
      this.Context.DeleteObject((SpareDevice)e.Element); 
      this.Context.DeleteObject((AreaDevice)e.Element); 
      this.Context.DeleteObject((Executor)e.Element); 
     } 
    } 

    protected override void InsertItem(int index, Area item) 
    { 
     item.Areas.AssociationChanged += new CollectionChangeEventHandler(Areas_AssociationChanged); 
     this.Context.AddToAreas(item); 
     base.InsertItem(index, item); 
    } 

    protected override void RemoveItem(int index) 
    { 
     Area a = this[index]; 
     a.Areas.AssociationChanged -= Areas_AssociationChanged; 
     for (int i = a.Areas.Count - 1; i >= 0; i--) 
     { 
      this.Context.DeleteObject(a.Areas.ElementAt(i)); 
     } 
     for (int i = a.SpareDevices.Count - 1; i >= 0; i--) 
     { 
      this.Context.DeleteObject(a.SpareDevices.ElementAt(i)); 
     } 
     for (int i = a.AreaDevices.Count - 1; i >= 0; i--) 
     { 
      this.Context.DeleteObject(a.AreaDevices.ElementAt(i)); 
     } 
     for (int i = a.Executors.Count - 1; i >= 0; i--) 
     { 
      this.Context.DeleteObject(a.Executors.ElementAt(i)); 
     } 
     this.Context.DeleteObject(this[index]); 
     base.RemoveItem(index); 
    } 
} 

轉換器類CS:

public class AreasConverter : IValueConverter 
{ 
    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     var item = value as Area; 
     return item.Areas.Where(a => a.ParentArea_ID == item.ID); 
    } 

    public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

XAML.cs:

public MainWindow() 
    { 
     InitializeComponent(); 
     AreasTreeView.ItemsSource = context.Areas.Where(a => a.ParentArea_ID == null); 
    }