开发者

Simple WPF data binding question with icons

I have a few types that make up a hierarchy like this:

+ Image0.Name
    Effect0.Name
    Effect1.Name
    Effect2.Name
    Layer0.Name
    Layer1.Name
    Layer2.Name
    ...
+ Image1.Name
    Effect0.Name
    Effect1.Name
    Effect2.Name
    Layer0.Name
    Layer1.Name
    Layer2.Name
    ...
+ Image2.Name
    Effect0.Name
    Effect1.Name
    Effect2.Name
    Layer0.Name
    Layer1.Name
    Layer2.Name
    ...

But I can't get my head around the data binding. Here is the code for the types:

public class Image
{
    public string Name { get; set; }

    public IEnumerable<Effect> Effects { get; set; }
    public IEnumerable<Layer> Layers { get; set; }
}

public class Effect
{
    public string Name { get; set; }

    public Effect ( string name )
    {
        this.Name = name;
    }
}

public class Layer
{
    public string Name { get; set; }

    public Layer ( string name )
    {
        this.Name = name;
    }
}

public class EditorView : INotifyPropertyChanged
{
    IEnumerable&l开发者_JS百科t;Node> images;
    public IEnumerable<Node> Images
    {
        get { return images; }
        set
        {
            this.images = value;
            this.RaisePropertyChanged ( "Images" );
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void RaisePropertyChanged ( string propertyName )
    {
        var handler = this.PropertyChanged;
        if ( handler != null )
            handler ( this, new PropertyChangedEventArgs ( propertyName ) );
    }
}

Additionally these types (Effect, Layer) has a unique icon per type, if you can also show how to bind this, that would help me a lot in understanding it all.


This is how I normally do it, create a base class for the child items and then create I property that returns all the child Items

 public class Image 
 { 
    public string Name { get; set;} 
    public IEnumerable<Effect> Effects { get; set; } 
    public IEnumerable<Layer> Layers { get; set; }
    public IEnumerable<Node> Nodes { get { return ((IEnumerable<Node>)Layers).Union((IEnumerable<Node>)Effects); } }
}

 public class Effect : Node
{
    public Effect(string name) 
    { 
        this.Name = name; 
    } 
}
public class Layer : Node
{ 
      public Layer(string name) { this.Name = name; } 
}

public class Node
{
    public string Name { get; set; }
    public Image Icon { get; set; }
}

You should be able to set the Image Property (url of image but you can change the property type) of the respective Effects and Layers and then I've already wired it up, this should work

 <TreeView Height="221" HorizontalAlignment="Left" Margin="12,12,0,0" Name="treeView1" 
              VerticalAlignment="Top" Width="479" ItemsSource="{Binding Images}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Nodes}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Name}"></TextBlock>
                    <Image Source="{Binding Icon}"></Image>
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

EDIT

And then set the TreeView Item's DataContext to your ViewModel, just as an example I did this in the code behind:

Image img = new Image();
Effect effect = new Effect("Effect1");
Layer layer = new Layer("Layer1");
img.Name = "Image1";
List<Effect> effects = new List<Effect>();
effects.Add(effect);
img.Effects = effects;
List<Layer> layers = new List<Layer>();
layers.Add(layer);
img.Layers = layers;
List<WpfApplication1.Image> Images = new List<Image>();
Images.Add(img);
EditorView ev = new EditorView();
ev.Images = Images;
treeView1.DataContext = ev;

EDIT2: Pasted complete code (without using statements):

namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new EditorView();
    }
}

public class Image 

{ 
    public string Name { get; set;} 
    public IEnumerable<Effect> Effects { get; set; } 
    public IEnumerable<Layer> Layers { get; set; }
    public IEnumerable<Node> Nodes { get { return ((IEnumerable<Node>)Layers).Union((IEnumerable<Node>)Effects); } }
}
public class Effect : Node
{
    public Effect(string name) 
    { 
        this.Name = name; 
    } 
}
public class Layer : Node
{ 
      public Layer(string name) { this.Name = name; } 
}

public class Node
{
    public string Name { get; set; }
    public string Icon { get; set; }
}

public class EditorView : INotifyPropertyChanged 
{
    public EditorView()
    {
        Image img = new Image();
        WpfApplication1.Effect effect = new WpfApplication1.Effect("Effect1");
        WpfApplication1.Layer layer = new Layer("Layer1");
        img.Name = "Image1";
        List<Effect> effects = new List<WpfApplication1.Effect>();
        effects.Add(effect);
        img.Effects = effects;
        List<Layer> layers = new List<Layer>();
        layers.Add(layer);
        img.Layers = layers;
        List<WpfApplication1.Image> Images = new List<Image>();
        Images.Add(img);
        this.Images = Images;
    }

    IEnumerable<Image> images;
    public IEnumerable<Image> Images 
    { 
        get 
    { 
            return images; 
    } 
        set { this.images = value; this.RaisePropertyChanged("Images"); 
        } 
    } public event 
        PropertyChangedEventHandler 
        PropertyChanged; 
    void RaisePropertyChanged(string propertyName) 
    { var handler = this.PropertyChanged; 
        if (handler != null)            

            handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
}
}


You need to implement the HierarchicalDataTemplate. For sample of it look at the last of this article - http://msdn.microsoft.com/en-us/library/ms742521.aspx and this one - http://blogs.msdn.com/b/chkoenig/archive/2008/05/24/hierarchical-databinding-in-wpf.aspx

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜