It works OK in WinForms and WPF without any problems and easy bind to the
DataGrid, ListBox and ListView in Winforms and WPF.
But it does not work properly in the Microsoft Blend 3. Actually Microsoft
Blend 3 does not want read list of items from TableView and list of
properties by using ITypedList. Microsoft Blend 3 display my TableView as an
object and not collection of items. How to solve that problem?
Screenshot of blend with commentaries -
http://img9.imageshack.us/img9/3739/msblend3.png
TableView classes
public abstract class AbstractTableView<TRecord> :
MarshalByValueComponent, ITableView,
INotifyPropertyChanged, ITableViewCallbacks, ISupportInitialize
where TRecord : AbstractRecord
{
//it is definition of columns in the CVS file and same list uses in
the ITypedList to retrieve list of properties
public FieldCollection Fields
{
get { return _fields; }
}
}
public abstract class BindableTableView<TRecord> :
AbstractTableView<TRecord>,
IListSource, IList<TRecord>, IList, ITypedList, IBindingList,
ICancelAddNew, INotifyCollectionChanged
where TRecord : AbstractRecord
{
}
public abstract class TableView<TRecord> : BindableTableView<TRecord>
where TRecord : TableViewRecord
{
}
public class TableView : TableView<TableViewRecord>
{
}
where AbstractRecord and TableViewRecord is
public class TableViewRecord : AbstractRecord
{
}
public abstract class AbstractRecord : IDataErrorInfo,
INotifyPropertyChanged, ICustomTypeDescriptor
{
}
Implementation of data provider TableViewDataProvider to work with TableView
public class TableViewDataProvider : DataSourceProvider
{
private TableView _tableView;
private DispatcherOperationCallback _onCompletedCallback;
public TableView TableView
{
get { return _tableView; }
set
{
_tableView = value;
base.OnPropertyChanged(new
PropertyChangedEventArgs("TableView"));
}
}
protected override void BeginQuery()
{
//base.BeginQuery();
Exception exception = null;
try
{
if (TableView != null && !TableView.IsOpened)
{
TableView.Open();
}
}
catch (Exception ex)
{
exception = ex;
}
base.OnQueryFinished(TableView, exception, CompletedCallback,
TableView);
}
private DispatcherOperationCallback CompletedCallback
{
get
{
if (this._onCompletedCallback == null)
{
this._onCompletedCallback = new
DispatcherOperationCallback(this.OnCompletedCallback);
}
return this._onCompletedCallback;
}
}
private object OnCompletedCallback(object arg)
{
return null;
}
}
Example of XAML from previous screenshot
<views:UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ...>
<views:Perspective.Resources>
<local:Database x:Key="database" ConnectionType="Local"
InitialCatalog="R:\SharedFiles\FamilyDataStore"/>
<local:TableView x:Key="recipeCategory" TableName="RecipeCategory"
Database="{StaticResource database}">
<local:TableView.Fields>
<local:Field Name="Name" DataType="String" />
<local:Field Name="Image" DataType="Blob" />
<local:Field Name="ImageIndex" DataType="Integer" />
</local:TableView.Fields>
<local:TableView.IsOpened>
<System:Boolean>true</System:Boolean>
</local:TableView.IsOpened>
</local:TableView>
<local:TableViewDataProvider x:Key="recipeCategoryDataProvider"
TableView="{StaticResource recipeCategory}"/>
<DataTemplate x:Key="recipeCategoryTemplate">
<Grid Height="36">
<Label Content="{Binding Name}" Margin="10,0,0,0"
VerticalContentAlignment="Center" />
</Grid>
</DataTemplate>
</views:Perspective.Resources>
<Grid x:Name="LayoutRoot">
<Border Width="200" Margin="10,10, 0, 10"
VerticalAlignment="Stretch" HorizontalAlignment="Left">
<ListBox ItemsSource="{Binding Source={StaticResource
recipeCategory}}"
ItemTemplate="{Binding Source={StaticResource
recipeCategoryTemplate}}" />
</Border>
....