I have a collection of Objects with dependencyproperties, and Observer patern as I feed realtime data in "AssetIHM" Object.
public class assetVM: DependencyObject ,IObserver
{
public assetVM(AssetIHM aihm)
{
ObserverCollectionSingleton.ObserverCollectionInstance.Add(this);
_aihm = aihm;
}
private string _assetname;
public string assetname
{
get { return _assetname; }
set
{
_assetname = value;
SetValue(assetnameprop, value);
}
}
public static readonly DependencyProperty assetnameprop =
DependencyProperty.Register("assetnameprop", typeof(string),typeof(assetVM), new UIPropertyMetadata(""));
...
I also have a UserControl, Which should display the information contained in the AssetVM object:
public partial class AssetPanel : UserControl
{
public assetVM Asset
{
get
{
return (assetVM)GetValue(assetProperty);
}
set
{
SetValue(assetProperty, value);
}
}
public static DependencyProperty assetProperty = DependencyProperty.Register(
"Asset", typeof(assetVM), typeof(AssetPanel), new PropertyMetadata(null, new PropertyChangedCallback(OnCurrentItemChanged)));
public AssetPanel(assetVM _Asset)
{
Asset = _Asset;
this.DataContext = this;
InitializeComponent();
...
}
public AssetPanel( )
{
this.DataContext = this;
InitializeComponent();
...
}
...
I my main windows, I have a ListBox,
<Window x:Class="ETRportfolio.MainWindow"
DataContext = "{Binding RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:UserControls="clr-namespace:ETRportfolio"
Title="MainWindow" Height="1200" Width="1425">
<StackPanel HorizontalAlignment="Left" Height="1153" VerticalAlignment="Top" Width="1400" Margin="10,10,-18,0">
<ListBox x:Name="Gridview" Height="800" >
<ListBox.ItemTemplate>
<DataTemplate>
<UserControls:AssetPanel Asset="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
MY problem is that I would like to feed my Usercontrol with the data contained is the collection of AssetVM.
public partial class MainWindow : Window
{
public static Dispatcher curDispatcher;
public ObservableCollection<assetVM> Datas
{
get
{
return (ObservableCollection<assetVM>)curDispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.DataBind,
(DispatcherOperationCallback)delegate { return GetValue(DataSProperty); },
DataSProperty);
}
set
{
curDispatcher.BeginInvoke(DispatcherPriority.DataBind,
(SendOrPostCallback)delegate { SetValue(DataSProperty, value); },
value);
}
}
public readonly DependencyProperty DataSProperty = DependencyProperty.Register("DataS", typeof(ObservableCollection<assetVM>), typeof(MainWindow), new PropertyMetadata(null, new PropertyChangedCallback(OnCurrentItemChanged)));
public MainWindow()
{
this.DataContext = this;
curDispatcher = this.Dispatcher;
Datas =new ObservableCollection<assetVM>();
InitializeComponent();
Gridview.ItemsSource = Datas;
addasset.addbtn.Click += onclik;
}
When the AssetPanel constructor is created, it doesn't bind with My AssetVM datas. I always pass through the empty constructor.
How Can I do that in XAML?
I guess the problem is there:
ListBox.ItemTemplate>
<DataTemplate>
<UserControls:AssetPanel Asset="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
Thks!
Edit::
I removed this.DataContext = this;
In the UserControl constructor, but the UserControl Constructor called when a DataObject
assetVM
is added to the ObservableCollection Datas, used as datasource for the Listview, is this the empty constructor. but not:
public AssetPanel(assetVM _Asset)
> {
> Asset = _Asset;
> InitializeComponent();
> ValuationInfo.ItemsSource = new List<string> { "%", "Value" };
> AVbox.ItemsSource = Enum.GetValues(typeof(AV)).Cast<AV>();
> }
So it doesn't bind.
Edit2::
private static void OnCurrentItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
AssetPanel instance = (AssetPanel)d;
instance.Asset = (assetVM)e.NewValue;
return;
}
It binds ! :)
Nevertheless, the Registered Dependency properties in the dataobject are not displayed.
This is my Assetpanel xaml:
<UserControl x:Class="ETRportfolio.AssetPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="152" d:DesignWidth="1400">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border BorderBrush="#FFDE6A6A" BorderThickness="1" Grid.Row="0" Grid.Column="0" Background="lightblue">
<TextBlock x:Name="assetnamebox" TextWrapping="Wrap" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl }, Path = assetnameprop, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="15"/>
</Border>
...
TextBlock x:Name="assetnamebox" TextWrapping="Wrap" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl }, Path = assetnameprop,
is not binding with assetVM.assetname VIA the DependencyProperty assetnameprop.
What is wrong there?
thks
Setting a UserControl's DataContext to itself, as done in your constructors by the statements
this.DataContext = this;
effectivly disables binding to properties of inherited DataContexts, like in
<ListBox.ItemTemplate>
<DataTemplate>
<UserControls:AssetPanel Asset="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
where the binding source is the inherited DataContext of the ListBoxItems, i.e. an assetVM
instance.
Remove the DataContext assignment from your UserContr's constructors.