Adam
Adam

Reputation: 1493

What are UserControls and ContentPresenters and how can I use them to display and change my content?

Edit: Oh my. I forgot to commit before changing my code and unfortunately the program is not running properly. I will try to describe what displays currently and what I hope to accomplish. What I currently have is a WPF window called SelectScreenShots. When the window loads it takes screen shots of all the active windows associated with the program and renders them as bitmaps, it loads the items control which displays two columns one containing all the images and one containing buttons.

When the user clicks on one of the images, I want that image to display in the same window only enlarged. There is a back button at the top of the window and when the user clicks the back button, I want it to go back to the list displaying all the images.

I am inexperienced with WPF. I have only made very simple GUIs, but I am trying to expand my knowledge. I am trying to build a GUI that displays all the active windows from an application and allows the user to click on an image in the list to display a large image. I was told I need to accomplish this using a UserControl and a ContentPresenter, but I don't understand how the two relate to each other and how to bind my list of images to the UserControl.

Originally I was using an ItemsControl. The xaml is below:

<ItemsControl Name="_itemsControl">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Name="_imageGrid">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="550"/>
                        <ColumnDefinition Width="250"/>
                    </Grid.ColumnDefinitions>
                    <Image Name="_image" Grid.Column="0" Height="400" Width="550" HorizontalAlignment="Center" VerticalAlignment ="Center" Stretch="Uniform" Source="{Binding ''}" 
                               MouseLeftButtonUp="Image_MouseLeftButtonUp"/>
                    <Grid Grid.Column="1">
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <Button Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Bottom" Name="_addscreenshot" Click="_addscreenshot_Click" Content="Select Screenshot" 
                                    Height="30" Width="150" Margin="3.5,0,3.5,7"/>
                        <Button Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Top" Name="_removescreenshot" Click="_removescreenshot_Click" Content="Remove Screenshot" 
                                    Height="30" Width="150" Margin="3.5,0,3.5,7"/>
                    </Grid>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

I am binding a list of bitmaps to _image in my code behind.

I am assuming I need to take this ItemsControl and transfer it over the UserControl and then display the UserControl in a ContentPresenter on my main window.

Forgive me if this is completely incorrect. I have tried doing my own research however the explanations are very broad and vague, I assume because UserControls are by nature broad and vague so that they can accomplish a number of tasks.

If anyone could point me in the right direction it would be greatly appreciated.

Upvotes: 1

Views: 210

Answers (1)

James Wright
James Wright

Reputation: 3010

The purpose of a ContentPresenter is to display the content within a ContentControl, an example being the Button class. As opposed to creating a new UserControl or using a ContentControl with a ContentPresenter, I'd create a custom control inheriting from the Control class. Here is a very basic (i.e. lack of MVVM and Styles) solution that I've devised.

The output of the code below is this:

enter image description here

ImageDialogue control

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace ImageControl
{
    public class ImageDialogue : Control
    {
        public ImageDialogue()
        {
            //applies the default style for the control (see ControlTemplate below)
            DefaultStyleKey = typeof (ImageDialogue);
        }

        public static readonly DependencyProperty ImageSourceProperty =
            DependencyProperty.Register("ImageSource", typeof (ImageSource), typeof (ImageDialogue), new PropertyMetadata(default(ImageSource)));

        public ImageSource ImageSource
        {
            get { return (ImageSource) GetValue(ImageSourceProperty); }
            set { SetValue(ImageSourceProperty, value); }
        }
    }
}

The default style (declared within App.xaml just for demonstrative purposes)

<Application.Resources>
    <ResourceDictionary>
        <!-- declaring the style and template without a key enables them to be consumed as the default style --> 
        <Style TargetType="{x:Type local:ImageDialogue}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:ImageDialogue}">
                        <Grid Background="DarkGray"
                              Height="{TemplateBinding Height}"
                              Width="{TemplateBinding Width}">
                            <Image Source="{TemplateBinding ImageSource}" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
</Application.Resources>

MainWindow.xaml

<Window x:Class="ImageControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ImageControl="clr-namespace:ImageControl"
        Title="MainWindow" Height="600" Width="800">
    <Grid>
        <ItemsControl>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

            <Image Source="http://2.bp.blogspot.com/-WuasmTMjMA4/TY0SS4TzIMI/AAAAAAAAFB4/6alyfOzWsqM/s640/flowers-wallpapers-love-blooms-roses-bunch-of-flowers.jpg"
                   Margin="5"
                   Stretch="UniformToFill"
                   Height="200"
                   Width="200"
                   MouseUp="Image_MouseUp" />

            <Image Source="http://3.bp.blogspot.com/-0JiC3dRE-Vg/UVx_ffJogLI/AAAAAAAAC2w/SxRqMIWfBro/s1600/flowers-pics-flower-colours.jpg"
                   Margin="5"
                   Stretch="UniformToFill"
                   Height="200"
                   Width="200"
                   MouseUp="Image_MouseUp" />

            <Image Source="http://1.bp.blogspot.com/-zoLd-fBa48A/UYoQqgrBqWI/AAAAAAAAABY/aQAT7EtZvUc/s1600/flowers-13.jpg"
                   Margin="5"
                   Stretch="UniformToFill"
                   Height="200"
                   Width="200"
                   MouseUp="Image_MouseUp" />
        </ItemsControl>

        <ImageControl:ImageDialogue x:Name="ImageDialogue"
                                    Visibility="Collapsed"
                                    Height="500"
                                    Width="500"
                                    VerticalAlignment="Center"
                                    VerticalContentAlignment="Center"
                                    HorizontalAlignment="Center"
                                    HorizontalContentAlignment="Center" />
    </Grid>
</Window>

MainWindow code-behind

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace ImageControl
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Image_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Image image = sender as Image;

            // the above is an implicit cast, thus the reference will be null if it fails
            if (image == null)
                return;

            ImageDialogue.ImageSource = image.Source;
            ImageDialogue.Visibility = Visibility.Visible;
        }
   }
}

Upvotes: 1

Related Questions