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>