I can't see the uc, well i can see it but it's clean, it's not null cause it show empty uc objects (the correct number of records that are in the db) But it happens only using the uc cause if i use simple data-binding without uc i can see every records. I've alredy done a breakpoint to see if for some reason the data passed with the dependency property was null, but there are every information in the object, simply it can't pass the data to the uc xaml.
Alredy tried without the uc and it works
UC XAML
<Grid>
<StackPanel>
<Button x:Name="elementoButton">
<Image x:Name="elementoImage" Width="64" Height="64"/>
</Button>
<TextBlock x:Name="ipTextBlock" HorizontalAlignment="Center"/>
<TextBlock x:Name="nomeTextBlock" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
UC C#
public Classes.Elementi elementi
{
get { return (Classes.Elementi)GetValue(elementiProperty); }
set { SetValue(elementiProperty, value); }
}
// Using a DependencyProperty as the backing store for elementi. This enables animation, styling, binding, etc...
public static readonly DependencyProperty elementiProperty =
DependencyProperty.Register("elementi", typeof(Classes.Elementi), typeof(ElementoControl), new PropertyMetadata(new Classes.Elementi { IndirizzoIP = "0.0.0.0", Nome = "Undefined", Image = "/Control Panel 2.0;component/img/default.png" }, SetElemento));
private static void SetElemento(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ElementoControl elementoControl = new ElementoControl();
if (elementoControl != null)
{
elementoControl.ipTextBlock.Text = (e.NewValue as Classes.Elementi).IndirizzoIP;
elementoControl.nomeTextBlock.Text = (e.NewValue as Classes.Elementi).Nome;
#region SetImage
if ((e.NewValue as Classes.Elementi).Categoria == "Uruk")
{
elementoControl.elementoImage.Source = new BitmapImage(new Uri((e.NewValue as Classes.Elementi).Image, UriKind.Relative));
}
else if ((e.NewValue as Classes.Elementi).Categoria == "Server")
{
elementoControl.elementoImage.Source = new BitmapImage(new Uri((e.NewValue as Classes.Elementi).Image, UriKind.Relative));
}
else if ((e.NewValue as Classes.Elementi).Categoria == "Router")
{
elementoControl.elementoImage.Source = new BitmapImage(new Uri((e.NewValue as Classes.Elementi).Image, UriKind.Relative));
}
else if ((e.NewValue as Classes.Elementi).Categoria == "Pannelli Solari")
{
elementoControl.elementoImage.Source = new BitmapImage(new Uri((e.NewValue as Classes.Elementi).Image, UriKind.Relative));
}
else if ((e.NewValue as Classes.Elementi).Categoria == "EasyCapture")
{
elementoControl.elementoImage.Source = new BitmapImage(new Uri((e.NewValue as Classes.Elementi).Image, UriKind.Relative));
}
else if ((e.NewValue as Classes.Elementi).Categoria == "Computer")
{
elementoControl.elementoImage.Source = new BitmapImage(new Uri((e.NewValue as Classes.Elementi).Image, UriKind.Relative));
}
else if ((e.NewValue as Classes.Elementi).Categoria == "Internet")
{
elementoControl.elementoImage.Source = new BitmapImage(new Uri((e.NewValue as Classes.Elementi).Image, UriKind.Relative));
}
else if ((e.NewValue as Classes.Elementi).Categoria == "Stampante")
{
elementoControl.elementoImage.Source = new BitmapImage(new Uri((e.NewValue as Classes.Elementi).Image, UriKind.Relative));
}
else if ((e.NewValue as Classes.Elementi).Categoria == "UPS")
{
elementoControl.elementoImage.Source = new BitmapImage(new Uri((e.NewValue as Classes.Elementi).Image, UriKind.Relative));
}
#endregion
#region IsPingable
if (IsPingable((e.NewValue as Classes.Elementi).IndirizzoIP))
{
elementoControl.elementoButton.Background = new SolidColorBrush(Colors.DarkGreen);
}
else
{
elementoControl.elementoButton.Background = new SolidColorBrush(Colors.DarkRed);
}
#endregion
}
else
MessageBox.Show("usercontrol nullo");
}
MainWindow XAML
<StackPanel>
<ListView x:Name="elementiListView" Background="DodgerBlue">
<ListView.ItemTemplate>
<DataTemplate>
<uc:ElementoControl elementi="{Binding}"/>
<!--<StackPanel>
<Button x:Name="elementoButton">
<Image x:Name="imageButton" Source="{Binding Image}" Width="64" Height="64"></Image>
</Button>
<TextBlock Text="{Binding Nome}" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding IndirizzoIP}" HorizontalAlignment="Center"/>
</StackPanel>-->
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
MainWindow C#
private void ReadDatabase()
{
List<Classes.Elementi> elementi = new List<Classes.Elementi>();
using (SQLiteConnection connection = new SQLiteConnection(App.ElementiDB()))
{
connection.CreateTable<Classes.Elementi>();
elementi = connection.Table<Classes.Elementi>().ToList();
}
if (elementi != null)
{
elementiListView.ItemsSource = elementi;
}
}
In the MainWindow XAML you can see that i've tried without the uc, and without it it works perfectly but i need to use the uc, i expect that either using the uc i can see the same thing that without it
First: DependencyObject d
is a reference to the ElementoControl
whose elementi
property was just set. But you ignore it. Instead, you create a new one, set properties on it, and throw the new one away. Naturally, the real control shows no sign of having its properties set, because you never touched them.
private static void SetElemento(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ElementoControl elementoControl = new ElementoControl();
// Why are you checking to see if this is null? You just created it.
if (elementoControl != null)
{
Do this instead:
private static void SetElemento(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// If anybody calls this method with a reference to something other than
// ElementoControl, that's a bug and an exception should be thrown.
if (!(d is ElementoControl))
{
throw new ArgumentException("d must be ElementoControl");
}
ElementoControl elementoControl = d as ElementoControl;
// This should be done mostly in XAML as well, but I don't have time at the
// moment. I would give ElementoControl a boolean readonly dependency property
// called IsPingable. I would set that property here, and in the XAML I would
// give the button a Style with a DataTrigger that set the Button's background
// color according to the value of IsPingable.
#region IsPingable
if (IsPingable((e.NewValue as Classes.Elementi).IndirizzoIP))
{
elementoControl.elementoButton.Background = new SolidColorBrush(Colors.DarkGreen);
}
else
{
elementoControl.elementoButton.Background = new SolidColorBrush(Colors.DarkRed);
}
#endregion
}
Second: Note that I omitted most of the above method. That's because you should be binding viewmodel properties in XAML. Note also that the vast majority of the above method was a long, long series of if/else branches all of which did the exact same thing. You don't need to decide sixteen different ways to do the same thing anyway. Just do it.
But the real takeaway here is that your UserControl "inherits" its DataContext from its parent, the DataTemplate in this case. For that reason, all those bindings that worked in the original DataTemplate will necessarily work identically in the UserControl (unless you break things by explicitly setting the UserControl's DataContext to something crazy, but from what I can see in your question, you didn't do that (if you did, don't)). UserControls are designed to work this way.
<Grid>
<StackPanel>
<Button x:Name="elementoButton">
<Image Source="{Binding Image}" Width="64" Height="64"/>
</Button>
<TextBlock Text="{Binding IndirizzoIP}" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding Nome}" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>