将usercontrol属性绑定到自定义类

时间:2017-09-29 09:58:53

标签: c# wpf

在我的应用程序中,我正在主窗口使用名为“ChannelControls”的usercontrol,我实例6次。

public partial class ChannelControls : UserControl
{
    CMiXData cmixdata = CMiXData.Instance;
    public ChannelControls()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    public static readonly DependencyProperty ChannelSpriteCountProperty =
    DependencyProperty.Register("ChannelSpriteCount", typeof(string), typeof(ChannelControls), new PropertyMetadata("1"));
    [Bindable(true)]
    public string ChannelSpriteCount
    {
        get { return (string)this.GetValue(ChannelSpriteCountProperty); }
        set { this.SetValue(ChannelSpriteCountProperty, value); }
    }

我正在使用一个名为cmixdata的自定义类来保存我的应用程序的所有数据(它将包含带有List字符串,double等的不同属性...)。 ChannelControls将包含许多滑块,按钮和其他用户控件,但目前我正在尝试绑定其中一个。

以下是此自定义类的一部分,它将保存数据,它有一个私有构造函数,因为我需要从任何地方访问它:

[Serializable]
public class CMiXData : INotifyPropertyChanged
{
    private static CMiXData _instance = null;
    public static CMiXData Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new CMiXData();
            }
            return _instance;
        }
    }
    private CMiXData() { } //prevent instantiation from outside the class


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


    private List<string> _SpriteCount = new List<string>(new string[] {"1", "1", "1", "1", "1", "1"});
    public List<string> SpriteCount
    {
        get { return _SpriteCount; }
        set
        {
            if(_SpriteCount != value)
            {
                _SpriteCount = value;
                RaisePropertyChanged("SpriteCount");
            }
        }
    }

以下是我试图将channelcontrol属性ChannelSpriteCount绑定到我的单例类:cmixdata。

<CMiX:ChannelControls x:Name="Layer0" Tag="0" Visibility="Visible" ChannelSpriteCount="{Binding SpriteCount[0], Mode=TwoWay}"/>

在实例ChannelControls的主用户控件上,datacontext以这种方式设置:

public partial class CMiX_UI : UserControl
{
    BeatSystem beatsystem = new BeatSystem();
    CMiXData cmixdata = CMiXData.Instance;

    public CMiX_UI()
    {
        InitializeComponent();
        this.DataContext = cmixdata;
    }

在xaml方面:

<UserControl
        x:Class="CMiX.CMiX_UI"
        DataContext="{x:Static CMiX:CMiXData.Instance}"

但由于某种原因,cmixdata中的属性未更新,并且始终具有默认值...

1 个答案:

答案 0 :(得分:2)

UserControl永远不应该拥有&#34;拥有&#34;视图模型的实例。相反,它应该具有绑定到&#34;外部&#34;的属性的依赖项属性。查看模型。

您的ChannelsControl会声明一个这样的属性(我认为string不适合计数):

public partial class ChannelsControl : UserControl
{
    public static readonly DependencyProperty SpriteCountProperty =
        DependencyProperty.Register(
            nameof(SpriteCount), typeof(string), typeof(ChannelsControl));

    public string SpriteCount
    {
        get { return (string)GetValue(SpriteCountProperty); }
        set { SetValue(SpriteCountProperty, value); }
    }

    ...
}

在ChannelsControl的XAML中,你可以像这样绑定它:

<CMiX:Counter Count="{Binding SpriteCount,
                      RelativeSource={RelativeSource AncestorType=UserControl}}"/>

现在您将使用如下所示的UserControl,其中您将Count属性绑定到DataContext中的视图模型,如下所示:

<Window.DataContext>
    <local:CMiXData />
</Window.DataContext>
...

<local:ChannelsControl SpriteCount="{Binding SpriteCount[0]}" ... />

您现在也可以在ItemsControl的ItemTemplate中使用ChannelsControl,如下所示:

<ItemsControl ItemsSource="{Binding SpriteCount}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:ChannelsControl SpriteCount="{Binding}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

编辑:将Window的DataContext设置为您的视图模型单例实例,如下所示:

<Window ... DataContext="{x:Static local:CMiXData.Instance}" >

或者在代码后面,在MainWindow构造函数中:

DataContext = CMiXData.Instance;