Why are my images not showing up in my UserControl

2019-09-05 07:52发布

I have a ContentPresenter that displays a UserControl. The UserControl contains an ItemsControl that binds to a list of images. When I change the DataContext for my UserControl the Images are there, they just aren't displaying. I think what is happening is they are just stacking on top of each other instead of wrapping, but I don't know why. Here is some code to give you a better idea of what I am working with.

Edit: To get a better of idea of how the program flows here is what is going on. ListOfScreenShots is another user control that displays images and buttons allowing users to select the images. As screen shots are selected they are added to a List<BitmapSource> and they are supposed to display in EnlargedScreenShots. Here is how the UserControl is applied

private void MainWindowCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) { if (e.Command == SelectImageCommand) { selectedImages.Add(e.Parameter as BitmapSource); ess.DataContext = selectedImages; this._contentPresenter2.Content = ess; } }

Here is the xaml for ListOfScreenShots. That should also give a clearer understanding of what is going on.

ListOfScreenShots xaml:

    <UserControl x:Class="Client.App.Support.ListOfScreenShots"
             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"
             xmlns:support="clr-namespace:Client.App.Support"
             d:DesignHeight="400" d:DesignWidth="800">
    <Grid>
        <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
            <ItemsControl Name="_listBox" ItemsSource="{Binding ''}">
                <!--<ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>-->
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <Image Name ="_thumbnailImage" Width="600" VerticalAlignment="Center" Source="{Binding ''}"/>
                            <Button VerticalAlignment="Center" HorizontalAlignment="Center" Name="_addscreenshot" Content="Select Screenshot" Command="{x:Static support:SelectScreenShots.SelectImageCommand}" 
                                    CommandParameter="{Binding ''}" Width="150" />
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    </Grid>
</UserControl>

Main Window xaml:

<dxc:DXWindow x:Class="Client.App.Support.SelectScreenShots"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/core" Focusable="False" IsTabStop="False"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
    xmlns:libRes="clr-namespace:Shared.Lib.Resources;assembly=Shared.Lib"
    xmlns:support="clr-namespace:Client.App.Support"
    Title="Select Images" Height="600" Width="800">

<Window.CommandBindings>
    <CommandBinding Command="support:SelectScreenShots.SelectImageCommand" Executed="MainWindowCommandBinding_Executed"/>
</Window.CommandBindings>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="367"/>
            <RowDefinition Height="167"/>
            <RowDefinition Height="33"/>
        </Grid.RowDefinitions>
        <ContentPresenter Grid.Row="0" Name="_contentPresenter" Content="{Binding ''}"/>
        <ContentPresenter Grid.Row="1" Name="_contentPresenter2" Content="{Binding ''}"/>
        <StackPanel Grid.Row="2" HorizontalAlignment="Right"  Orientation="Horizontal">
            <Button Name="_OK_Button" Content="OK" Click="_OK_Button_Click" Margin="0,5,5,5" Width="75" Height="23"/>
            <Button Name="_Cancel_Button" Content="Cancel" Click="_Cancel_Button_Click" Margin="0,5,5,5" Width="75" Height="23"/>
        </StackPanel>
    </Grid>

Main Window code behind:

    public partial class SelectScreenShots : DXWindow
{
    public static readonly RoutedCommand SelectImageCommand = new RoutedCommand();

    public static List<BitmapSource> selectedImages = new List<BitmapSource>();
    public static List<BitmapSource> screenshots = new List<BitmapSource>();
    public static ListOfScreenShots loss = new ListOfScreenShots();
    public static EnlargedScreenShot ess = new EnlargedScreenShot();

    public SelectScreenShots()
    {
        Client.GUI.AppGUI.SetupTheme(this);
        InitializeComponent();
        screenshots = RenderWindows();
        loss.DataContext = screenshots;
        this._contentPresenter.Content = loss;
    }

    public static List<BitmapSource> RenderWindows()
    {
        var windows = Application.Current.Windows
                                         .OfType<Window>()
                                         .Where(x => x.GetType() != typeof(AskAQuestionDialog) & x.GetType() != typeof(SelectScreenShots));

        var bitmaps = new List<BitmapSource>();

        foreach (var window in windows)
        {
            var bitmap = new RenderTargetBitmap((int)window.Width, (int)window.Height, 96d, 96d, PixelFormats.Default);
            bitmap.Render(window);

            bitmaps.Add(bitmap);
        }

        return bitmaps;
    }


    private void MainWindowCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        if (e.Command == SelectImageCommand)
        {
            selectedImages.Add(e.Parameter as BitmapSource);
            ess.DataContext = selectedImages;
            this._contentPresenter2.Content = ess;
        }
    }


    private void _OK_Button_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }

    private void _Cancel_Button_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }
}
}

User Control xaml:

<UserControl x:Class="Client.App.Support.EnlargedScreenShot"
         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="162" d:DesignWidth="800">
<Grid>
    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
        <StackPanel Orientation="Horizontal">
            <ItemsControl Name="_itemsControl" ItemsSource="{Binding ''}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                        <Image Name ="_thumbnailImage" HorizontalAlignment="Left" VerticalAlignment="Center" Source="{Binding ''}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        </StackPanel>
    </ScrollViewer>
</Grid>

There are some other things going on as far as sizing and scroll bar visibility not working properly, but I will work those out later. Right now this is really bugging me.

Anyone see anything obviously wrong. I am going to guess it has something to do with the fact that I have everything wrapped in a stack panel, but before I just had the image inside the DataTemplate wrapped in a StackPanel and it still didn't work. I also tried removing the StackPanel altogether and just using the WrapPanel.

Any help would be greatly appreciated. Thank you.

3条回答
Root(大扎)
2楼-- · 2019-09-05 08:09

My guesses:

1) your UserControl is sized as 0;0 so you won't see anything. Bind UserControl Width/Height to ContentPresenter Width/Height, as so:

<UserControl x:Class="Client.App.Support.EnlargedScreenShot"
         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" 
         Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
         Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
         d:DesignHeight="162" d:DesignWidth="800">

2) Add Width/Height properties to Image element, set it explictly for testing. Also add TextBlock and bind Text against Image.Source to see if bindings work finely.

This problem needs help of Snoop(WPF Spy utility) that will answer this question in matter of minutes, so perhaps this is the most useful suggestion for now: http://snoopwpf.codeplex.com/

Ps you are sharing the same BitmapSource between two controls. I don't exactly know, but this might be the fishy part too. So if you can, try duplicating it.

查看更多
成全新的幸福
3楼-- · 2019-09-05 08:31

Too many things going on to give a definitive answer but one thing that immediately springs to mind is you aren't doing property change notification. Try switching your lists to ObservableCollection and read this MSDN article on the subject.

查看更多
ら.Afraid
4楼-- · 2019-09-05 08:32

I was doing something very obviously wrong in my code behind.

I wasn't instantiating a new instance of EnlargedScreenShot when my command was executed. It was being instantiated once, when the window loaded and then I wasn't updating it. I just had to move

EnlargedScreenShot ess = new EnlargedScreenShot();

Into here:

private void MainWindowCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    EnlargedScreenShot ess = new EnlargedScreenShot();
    if (e.Command == SelectImageCommand)
    {
        selectedImages.Add(e.Parameter as BitmapSource);
        ess.DataContext = selectedImages;
        this._contentPresenter2.Content = ess;
    }
}
查看更多
登录 后发表回答