C# 装订范围-款式及;模板

C# 装订范围-款式及;模板,c#,.net,wpf,data-binding,styles,C#,.net,Wpf,Data Binding,Styles,我的项目中有一个自定义的ItemsControl,我正在尝试为它编写一种样式,将静态项列表与控件本身的依赖项属性上的项列表相结合 以下是我的资源字典中相应的XAML: <x:Array Type="{x:Type System:Object}" x:Key="Static_CloudItems"> <Button>One</Button> <Button>Two</Button> <Button>Th

我的项目中有一个自定义的
ItemsControl
,我正在尝试为它编写一种样式,将静态项列表与控件本身的依赖项属性上的项列表相结合

以下是我的资源字典中相应的XAML:

<x:Array Type="{x:Type System:Object}" x:Key="Static_CloudItems">
    <Button>One</Button>
    <Button>Two</Button>
    <Button>Three</Button>
</x:Array>

<Style TargetType="{x:Type ControlsBase:CloudControl}" x:Key="BasicCloudStyle">
    <Setter Property="ItemsSource">
        <Setter.Value>
            <CompositeCollection>
                <CollectionContainer Collection="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ControlsBase:CloudControl}}, Path=CloudItems}" />
                <CollectionContainer Collection="{StaticResource Static_CloudItems}" />
            </CompositeCollection>
        </Setter.Value>
    </Setter>
</Style>

一个
两个
三
然后是我的控件/窗口/任何内容中的相应代码:

<ControlsBase:CloudControl Style="{DynamicResource BasicCloudStyle}">
    <ControlsBase:CloudControl.CloudItems>
        <x:Array Type="{x:Type System:Object}">
            <Button>Four</Button>
            <Button>Five</Button>
        </x:Array>
    </ControlsBase:CloudControl.CloudItems>
</ControlsBase:CloudControl>

四
五
其思想是,样式应该将静态元素与控件的每个实例版本上定义的任何元素相结合


我的问题是,上面的绑定不起作用(我也意识到了原因!),所以我需要一种能够绑定到样式的父级的方法,但是由于setter不在视觉/逻辑树中,所以我对如何继续这个属性有点困惑

如何实现一个IValueConverter,为幕后的控件构建正确的CompositeCollection?见下面的示例:

XAML:


一个
两个
三
项目1
项目2
项目3
代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

public class MyControl : ListBox 
{
    public ObservableCollection<object> InstanceItems
    {
        get { return (ObservableCollection<object>)GetValue(InstanceItemsProperty); }
        set { SetValue(InstanceItemsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for InstanceItems.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty InstanceItemsProperty =
        DependencyProperty.Register("InstanceItems", typeof(ObservableCollection<object>), 
        typeof(MyControl), new UIPropertyMetadata(new ObservableCollection<object>()));
}

public class MyItemsSourceConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        MyControl mc = value as MyControl;
        if (mc != null)
        {
            CompositeCollection cc = new CompositeCollection();

            CollectionContainer container1 = new CollectionContainer();
            BindingOperations.SetBinding(container1, CollectionContainer.CollectionProperty,
                new Binding()
                {
                    Source = mc,
                    Path = new PropertyPath("InstanceItems")
                });
            cc.Add(container1);

            CollectionContainer container2 = new CollectionContainer()
            {
                Collection = mc.FindResource("Static_CloudItems") as Array
            };

            cc.Add(container2);

            return cc;
        }
        return null;
    }

    public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new System.NotImplementedException();
    }

    #endregion
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
}
公共类MyControl:列表框
{
公共可观察收集实例项
{
get{return(ObservableCollection)GetValue(InstanceItemsProperty);}
set{SetValue(InstanceItemsProperty,value);}
}
//使用DependencyProperty作为InstanceItems的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性InstanceItemsProperty=
DependencyProperty.Register(“InstanceItems”),typeof(ObservableCollection),
typeof(MyControl),新的UIPropertyMetadata(新的ObservableCollection());
}
公共类MyItemsSourceConverter:IValueConverter
{
#区域转换器成员
公共对象转换(对象值、System.Type targetType、对象参数、System.Globalization.CultureInfo区域性)
{
MyControl mc=作为MyControl的值;
如果(mc!=null)
{
CompositeCollection cc=新的CompositeCollection();
CollectionContainer1=新的CollectionContainer();
BindingOperations.SetBinding(container1,CollectionContainer.CollectionProperty,
新绑定()
{
来源=mc,
路径=新属性路径(“InstanceItems”)
});
抄送添加(集装箱1);
CollectionContainer2=新的CollectionContainer()
{
Collection=mc.FindResource(“Static_CloudItems”)作为数组
};
抄送添加(集装箱2);
返回cc;
}
返回null;
}
公共对象转换回(对象值、System.Type targetType、对象参数、System.Globalization.CultureInfo区域性)
{
抛出新系统。NotImplementedException();
}
#端区
}
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

public class MyControl : ListBox 
{
    public ObservableCollection<object> InstanceItems
    {
        get { return (ObservableCollection<object>)GetValue(InstanceItemsProperty); }
        set { SetValue(InstanceItemsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for InstanceItems.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty InstanceItemsProperty =
        DependencyProperty.Register("InstanceItems", typeof(ObservableCollection<object>), 
        typeof(MyControl), new UIPropertyMetadata(new ObservableCollection<object>()));
}

public class MyItemsSourceConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        MyControl mc = value as MyControl;
        if (mc != null)
        {
            CompositeCollection cc = new CompositeCollection();

            CollectionContainer container1 = new CollectionContainer();
            BindingOperations.SetBinding(container1, CollectionContainer.CollectionProperty,
                new Binding()
                {
                    Source = mc,
                    Path = new PropertyPath("InstanceItems")
                });
            cc.Add(container1);

            CollectionContainer container2 = new CollectionContainer()
            {
                Collection = mc.FindResource("Static_CloudItems") as Array
            };

            cc.Add(container2);

            return cc;
        }
        return null;
    }

    public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new System.NotImplementedException();
    }

    #endregion
}