WPF自定义控件问题

时间:2010-05-26 16:53:44

标签: c# wpf xaml custom-controls

我遇到了问题,但我还没有找到解决方案。我想创建一个基本自定义控件并在另一个自定义控件中使用它。我在窗口中使用它时基本控件工作正常,但是当我在其他自定义控件中使用它时,绑定不起作用。

我的代码出了什么问题?

代码:

型号:

public class ElementModel
{
    public string Name { get; set; }
    public string FullName { get; set; }
}

基础控制:

public class ListControl : Control
{        
    static ListControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ListControl), new FrameworkPropertyMetadata(typeof(ListControl)));
    }

    public ListControl()
    {
        SetValue(ElementListProperty, new List<ElementModel>());
    }

    public static readonly DependencyProperty ElementListProperty =
        DependencyProperty.Register(
        "ElementList", 
        typeof(List<ElementModel>), 
        typeof(ListControl),
        new FrameworkPropertyMetadata(new List<ElementModel>())
      );

    public List<ElementModel> ElementList
    {
        get { return (List<ElementModel>)GetValue(ElementListProperty); }
        set { SetValue(ElementListProperty, value); }
    }
}

包装控件:

public class ListWrapper : Control
{
    static ListWrapper()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ListWrapper), new FrameworkPropertyMetadata(typeof(ListWrapper)));
    }

    public ListWrapper()
    {
        SetValue(EMListProperty, new List<ElementModel>());
    }

    public static readonly DependencyProperty EMListProperty =
       DependencyProperty.Register(
       "EMList",
       typeof(List<ElementModel>),
       typeof(ListWrapper),
       new FrameworkPropertyMetadata(new List<ElementModel>())
     );

    public List<ElementModel> EMList
    {
        get { return (List<ElementModel>)GetValue(EMListProperty); }
        set { SetValue(EMListProperty, value); }
    }
}

File Generic.xaml:

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:UIControl">

<Style TargetType="{x:Type local:ListControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ListControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">

                    <ListBox ItemsSource="{TemplateBinding ElementList}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel>
                                    <Label Content="Name:"/>
                                    <TextBlock Text="{Binding Path=Name}" />
                                    <Label Content="Full name:"/>
                                    <TextBlock Text="{Binding Path=FullName}" />
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type local:ListWrapper}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ListWrapper}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">

                    <local:ListControl ElementList="{TemplateBinding EMList}" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

如果我将控件放在窗口和绑定属性中,那么ListControl工作正常并显示元素,但WrapperList不会。

<Window x:Class="MainApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:UIControl;assembly=UIControl"
Title="Window1" Height="304" Width="628">
<Grid>
    <ui:ListControl x:Name="listCtr" ElementList="{Binding Path=EList}" HorizontalAlignment="Left" Width="300" />
    <ui:ListWrapper x:Name="listWrp" EMList="{Binding Path=EList}" HorizontalAlignment="Right" Width="300"  Background="Gray"/>
</Grid>

测试数据注入:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        DataContext = this;
    }

    List<ElementModel> elist = null;
    public List<ElementModel> EList
    {
        get
        {
            if (elist == null)
            {
                elist = new List<ElementModel>();
                ElementModel em = new ElementModel() { Name = "Apple", FullName = "Red Apple" };
                elist.Add(em);

                em = new ElementModel() { Name = "Pineapple", FullName = "Yellow Pineapple" };
                elist.Add(em);
            }
            return elist;
        }
    }
}

Project archive

2 个答案:

答案 0 :(得分:2)

我不知道为什么,但是如果我将这个元素列表(List)包装成新的集合类型(例如ElementCollection:ObservalbeCollection)并在依赖属性中使用这个集合类型,它工作正常...

public static readonly DependencyProperty EMListProperty =
   DependencyProperty.Register(
   "EMList",
   typeof(ElementCollection),
   typeof(ListWrapper),
   new FrameworkPropertyMetadata(new ElementCollection())
 );

public ElementCollection EMList
{
    get { return (ElementCollection)GetValue(EMListProperty); }
    set { SetValue(EMListProperty, value); }
}

答案 1 :(得分:0)

我找不到你设置绑定上下文的任何地方:

http://msdn.microsoft.com/en-us/library/ms752347.aspx