tbiro.com

Forums 
   HackPerfCounter
   RADPass
   SHEdit
   Toys
 
   Contact me
   My PGP Key
 

ListBox Data Binding With In-place Editing



How to get this code going:
  • Create a Windows Presentation Foundation project named ListBoxSample4
  • Add a new class file named Computer.cs
  • Add a new class file named ComputerTemplateSelector.cs
  • Paste the following code into the corresponding files.

Replace the contents of Window1.xaml with this:

<Window x:Class="ListBoxSample4.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Title="Window1" Height="307" Width="291">

    <Window.Resources>
        <DataTemplate x:Key="compEditingTemplate" x:Name="compEditingTemplate">
            <StackPanel>
                <TextBox Text="{Binding Path=Name}" Name="computerName" LostFocus="computerName_LostFocus" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="compTemplate" x:Name="compTemplate">
            <StackPanel>
                <TextBlock FontSize="14" Text="{Binding Path=Name}" />
                <TextBlock FontSize="10" Text="{Binding Path=Location}" />
                <TextBlock FontSize="10" Text="{Binding Path=Make}" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="compBrokenTemplate" x:Name="compBrokenTemplate">
            <StackPanel>
                <TextBlock FontSize="14" Foreground="Red" Text="{Binding Path=Name}" />
                <TextBlock FontSize="10" Foreground="Red" Text="Broken" />
            </StackPanel>
        </DataTemplate>
    </Window.Resources>

    <Grid Name="mainGrid" Background="AntiqueWhite">
        <ListBox Name="computerList" Margin="0,35,0,52" />

        <Button Height="23" Name="button1" VerticalAlignment="Bottom" Click="button1_Click">Pick me!</Button>
        <Button Height="23" Width="120" Name="button2" VerticalAlignment="Bottom" HorizontalAlignment="Left" 
                Margin="10,0,0,25" Click="button2_Click">Break</Button>
        <Button Height="23" Width="120" Name="button3" VerticalAlignment="Bottom" HorizontalAlignment="Right" 
                Margin="0,0,10,25" Click="button3_Click">Fix</Button>
        <TextBlock Height="24" Name="textBlock1" VerticalAlignment="Top" Margin="0,9,0,0">
            Select a ListBox item and press F2 to edit the name.
        </TextBlock>

    </Grid>

</Window>

Replace the contents of Window1.xaml.cs with this:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;

namespace ListBoxSample4
{
    public partial class Window1 : Window
    {
        public Boolean editStarted = false;

        public Window1()
        {
            InitializeComponent();

            ComputerTemplateSelector templateSelector = new ComputerTemplateSelector();

            templateSelector.CompTemplate = Resources["compTemplate"] as DataTemplate;
            templateSelector.CompBrokenTemplate = Resources["compBrokenTemplate"] as DataTemplate;
            templateSelector.CompEditingTemplate = Resources["compEditingTemplate"] as DataTemplate;

            computerList.IsSynchronizedWithCurrentItem = true;
            
            computerList.ItemTemplateSelector = templateSelector;

            computerList.ItemsSource = Computer.SampleComputers();

            computerList.KeyUp += new KeyEventHandler(computerList_KeyUp);

            computerList.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
        }

        void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
        {
            if (computerList.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated && 
                ComputerTemplateSelector.EditedComputerId != null &&
                !editStarted)
            {
                TextBox comp = FindChild(computerList, "computerName") as TextBox;
                comp.SelectAll();
                comp.Focus();

                editStarted = true;

            }
        }

        void computerList_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.F2)
            {
                // enter edit mode for the current item

                Computer selectedComputer = computerList.SelectedItem as Computer;

                if (selectedComputer != null)
                {
                    ComputerTemplateSelector.EditedComputerId = selectedComputer.ComputerId;

                    computerList.Items.Refresh();
                }
            }
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Computer selectedComputer = computerList.SelectedItem as Computer;

            if (selectedComputer == null)
            {
                MessageBox.Show("Select something");
                return;
            }

            MessageBox.Show("You have selected " + selectedComputer.Name);
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            Computer selectedComputer = computerList.SelectedItem as Computer;

            if (selectedComputer == null)
            {
                MessageBox.Show("Select something");
                return;
            }

            selectedComputer.IsBoken = true;

            // update UI
            computerList.Items.Refresh();
        }

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            Computer selectedComputer = computerList.SelectedItem as Computer;

            if (selectedComputer == null)
            {
                MessageBox.Show("Select something");
                return;
            }

            selectedComputer.IsBoken = false;

            // update UI
            computerList.Items.Refresh();

        }

        private void computerName_LostFocus(object sender, RoutedEventArgs e)
        {
            // end editing

            ComputerTemplateSelector.EditedComputerId = null;

            computerList.Items.Refresh();

            editStarted = false;
        }

        private static DependencyObject FindChild(DependencyObject dependencyObject, String childName)
        {
            if (dependencyObject == null) 
            {
                return null;
            }

            if (dependencyObject is FrameworkElement &&
                (dependencyObject as FrameworkElement).Name == childName)
            {
                return dependencyObject;
            }

            DependencyObject result = null;

            for (int index = 0; index < VisualTreeHelper.GetChildrenCount(dependencyObject); index++)
            {
                result = FindChild(VisualTreeHelper.GetChild(dependencyObject, index), childName);

                if (result != null)
                {
                    break;
                }
            }

            return result;
        }
    }
}

Replace the contents of Computer.cs with this:

using System;
using System.Collections.Generic;

namespace ListBoxSample4
{
    public class Computer
    {
        private static List<Computer> sampleComputers = null;

        public String Name { get; set; }
        public String Location { get; set; }
        public String Make { get; set; }
        public Boolean IsBoken { get; set; }

        private String computerId;

        public string ComputerId
        {
            get { return computerId; }
        }


        public Computer(String name, String location, String make)
            : this(name, location, make, false)
        {
        }

        public Computer(String name, String location, String make, Boolean isBroken)
        {
            Name = name;
            Location = location;
            Make = make;
            IsBoken = isBroken;

            computerId = Guid.NewGuid().ToString();
        }

        public static IEnumerable<Computer> SampleComputers()
        {
            if (sampleComputers == null)
            {
                sampleComputers = new List<Computer>();

                sampleComputers.Add(new Computer("Kitchen PC", "On the kitchen counter", "DELL AX443"));
                sampleComputers.Add(new Computer("NAS", "Network attached storage", "NSLU2"));
                sampleComputers.Add(new Computer("Media1", "Media server", "DELL VISTA"));
                sampleComputers.Add(new Computer("XBOX360", "Playing more", "MS", true));
                sampleComputers.Add(new Computer("KidPC", "Kids play stuff", "HP1"));
            }

            return sampleComputers;
        }
    }
}

Replace the contents of ComputerTemplateSelector.cs with this:

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

namespace ListBoxSample4
{
    public class ComputerTemplateSelector : DataTemplateSelector
    {
        public static string EditedComputerId = null;

        private DataTemplate compTemplate;
        private DataTemplate compBrokenTemplate;
        private DataTemplate compEditingTemplate;

        public DataTemplate CompTemplate
        {
            get { return compTemplate; }
            set { compTemplate = value; }
        }

        public DataTemplate CompBrokenTemplate
        {
            get { return compBrokenTemplate; }
            set { compBrokenTemplate = value; }
        }

        public DataTemplate CompEditingTemplate
        {
            get { return compEditingTemplate; }
            set { compEditingTemplate = value; }
        }

        public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
        {
            Computer computer = item as Computer;

            if (computer == null)
            {
                throw new ArgumentException("Item must be a Computer");
            }

            if (computer.ComputerId == EditedComputerId)
            {
                return compEditingTemplate;
            }
            else
            {
                if (!computer.IsBoken)
                {
                    return compTemplate;
                }
                else
                {
                    return compBrokenTemplate;
                }
            }
        }
    }
}

Compile and run.



Comment in the forum





Sitemap generated by Sitemap Manager