UserControl 不显示数据
UserControl doesn't show the data
我看不到 uc,我可以看到它,但它很干净,它不是空的,因为它显示空的 uc 对象(数据库中正确的记录数)
但它只发生在使用 uc 的情况下,如果我使用没有 uc 的简单数据绑定,我可以看到每条记录。我已经做了一个断点来查看是否由于某种原因与依赖项 属性 一起传递的数据为空,但是对象中有所有信息,只是它无法将数据传递给 uc xaml.
已经在没有 uc 的情况下尝试过并且有效
UCXAML
<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");
}
主窗口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>
主窗口 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;
}
}
在 MainWindow XAML 中你可以看到我已经尝试过没有 uc,没有它它工作得很好但是我需要使用 uc,我希望要么使用 uc 我可以看到没有它也是一样
首先:DependencyObject d
是对刚刚设置了 elementi
属性 的 ElementoControl
的引用。但是你忽略它。相反,您创建一个新的,在其上设置属性,然后丢弃新的。自然地,真正的控件没有显示其属性设置的迹象,因为您从未接触过它们。
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)
{
改为这样做:
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
}
其次:注意上面的方法我省略了大部分。那是因为您应该在 XAML 中绑定视图模型属性。另请注意,上述方法的绝大部分是一长串 if/else 分支,所有这些分支都做完全相同的事情。无论如何,你不需要决定十六种不同的方法来做同样的事情。去做就对了。
但这里真正的收获是您的 UserControl "inherits" 它的 DataContext 来自其父级,在本例中为 DataTemplate。出于这个原因,所有在原始 DataTemplate 中工作的绑定都必须在 UserControl 中以相同的方式工作(除非你通过将 UserControl 的 DataContext 显式设置为疯狂的东西来破坏事情,但从我在你的问题中看到的,你没有做那(如果你做了,不要))。 UserControls 被设计为以这种方式工作。
<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>
我看不到 uc,我可以看到它,但它很干净,它不是空的,因为它显示空的 uc 对象(数据库中正确的记录数) 但它只发生在使用 uc 的情况下,如果我使用没有 uc 的简单数据绑定,我可以看到每条记录。我已经做了一个断点来查看是否由于某种原因与依赖项 属性 一起传递的数据为空,但是对象中有所有信息,只是它无法将数据传递给 uc xaml.
已经在没有 uc 的情况下尝试过并且有效
UCXAML
<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");
}
主窗口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>
主窗口 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;
}
}
在 MainWindow XAML 中你可以看到我已经尝试过没有 uc,没有它它工作得很好但是我需要使用 uc,我希望要么使用 uc 我可以看到没有它也是一样
首先:DependencyObject d
是对刚刚设置了 elementi
属性 的 ElementoControl
的引用。但是你忽略它。相反,您创建一个新的,在其上设置属性,然后丢弃新的。自然地,真正的控件没有显示其属性设置的迹象,因为您从未接触过它们。
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)
{
改为这样做:
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
}
其次:注意上面的方法我省略了大部分。那是因为您应该在 XAML 中绑定视图模型属性。另请注意,上述方法的绝大部分是一长串 if/else 分支,所有这些分支都做完全相同的事情。无论如何,你不需要决定十六种不同的方法来做同样的事情。去做就对了。
但这里真正的收获是您的 UserControl "inherits" 它的 DataContext 来自其父级,在本例中为 DataTemplate。出于这个原因,所有在原始 DataTemplate 中工作的绑定都必须在 UserControl 中以相同的方式工作(除非你通过将 UserControl 的 DataContext 显式设置为疯狂的东西来破坏事情,但从我在你的问题中看到的,你没有做那(如果你做了,不要))。 UserControls 被设计为以这种方式工作。
<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>