0

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.

Adam
  • 1,483
  • 4
  • 21
  • 50
  • It's not easy to follow what's going on here. What is `ListOfScreenShots`? Where is the `UserControl` applied? – McGarnagle Dec 23 '13 at 21:33
  • You sure there is a Image in the e.Parameter inside the MainWindowCommandBinding_Executed? – Jurica Smircic Dec 23 '13 at 21:34
  • @jure yes there is a command parameter. I posted the xaml from `ListOfScreenshots` where the parameter, comes from. The images are being added to the `UserControl`, they are just not displaying properly. – Adam Dec 23 '13 at 21:49
  • @Adam, does receiving an BitmapSource in the Buttons COmmandHandler work? Do you see buttons at all? – Erti-Chris Eelmaa Dec 23 '13 at 21:52
  • @Erti-ChrisEelmaa yes, this part of the code: ` 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; } }' When I debug, add two images, and inspect ess, I can see that the images are being passed successfully. All my buttons load fine the images are not displaying in `_contentPresenter2` – Adam Dec 23 '13 at 21:56

3 Answers3

0

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.

Mark Feldman
  • 15,731
  • 3
  • 31
  • 58
  • Sorry about that Mark. I know my code is pretty ugly. Maybe the real answer to clean it up first and by doing that I will find the solution. Should I delete this question? – Adam Dec 23 '13 at 21:44
0

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.

Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • There's also the WPF visualizer...add a breakpoint in code-behind that you call with a button click handler or something, add your control to the watch window and click on the little magnifying glass. You can then traverse the visual tree and see exactly which parts are rendering what. – Mark Feldman Dec 23 '13 at 23:07
  • @Erti-Chris Eelmaa thanks for the suggestions. None of them worked. The bindings are working correctly, and there doesn't seem to be a problem with passing the BitmapSource between user controls. The BitmapSources are definitely getting passed properly and set as the ItemSource, I think there is something wrong with my xaml. I will see what snoop reveals. – Adam Dec 24 '13 at 13:03
0

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;
    }
}
Adam
  • 1,483
  • 4
  • 21
  • 50