UserControl不显示数据

时间:2019-05-01 13:42:55

标签: c# wpf data-binding user-controls

我看不到uc,我可以看到它,但是它很干净,它不是null,因为它显示了空的uc对象(数据库中正确的记录数) 但是,仅当使用uc原因时,如果我使用不带uc的简单数据绑定就可以看到每条记录,那么它就会发生。我已经做了一个断点,以查看是否出于某种原因通过dependency属性传递的数据为空,但是对象中包含了所有信息,只是无法将数据传递给uc xaml。

Alredy尝试了不带uc的情况,并且有效

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;
            }
        }

在MainWindow XAML中,您可以看到我尝试了不使用uc的情况,并且没有uc的情况也很好,但是我需要使用uc,我希望无论使用uc还是可以看到与不使用uc相同的东西< / p>

1 个答案:

答案 0 :(得分:0)

首先:DependencyObject d是对ElementoControl属性刚刚设置的elementi的引用。但是你忽略了它。相反,您可以创建一个新的,在其上设置属性,然后将新的扔掉。自然,真正的控件不会显示设置其属性的迹象,因为您从未碰过它们。

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中绑定viewmodel属性。还要注意,上述方法的绝大多数是很长的if / else分支系列,所有分支都执行完全相同的操作。无论如何,您无需决定十六种不同的方式来做同一件事。去做就对了。

但是真正的收获是您的UserControl从其父级(在本例中为DataTemplate)“继承”了其DataContext。因此,在原始DataTemplate中起作用的所有那些绑定在UserControl中都必须完全相同(除非您通过将UserControl的DataContext显式设置为疯狂的东西来破坏事物,但是从我的问题中可以看出,您没有做(如果您这样做了,那就不要)。 UserControl设计为以这种方式工作。

<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>