简体   繁体   English

将usercontrol属性绑定到自定义类

[英]Binding usercontrol property to custom class

In my application I'm using a usercontrol called "ChannelControls" which I instance 6 times, on the mainwindow. 在我的应用程序中,我使用了一个名为“ 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); }
    }

I'm making using a custom class called cmixdata to hold all the data for my application (it will contains different properties with List of string, double etc...). 我正在使用一个名为cmixdata的自定义类来保存我的应用程序的所有数据(它将包含具有字符串List ,双精度型等的不同属性)。 The ChannelControls will contains many sliders, button and other usercontrols but at the moment I'm trying to bind just one of them. ChannelControls将包含许多滑块,按钮和其他用户控件,但此刻我仅尝试绑定其中之一。

Here is one part of this custom class that will hold the data, it has a private constructor as I need to access it from anywhere : 这是该自定义类的一部分,它将保存数据,它有一个私有构造函数,因为我需要从任何地方访问它:

[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");
            }
        }
    }

And here is how I'm trying to bind the channelcontrol property ChannelSpriteCount to my singleton class : cmixdata. 这就是我试图将channelcontrol属性ChannelSpriteCount绑定到我的单例类:cmixdata的方法。

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

On the main usercontrol, which ChannelControls is instanced, the datacontext is set this way : 在主用户控件(实例化ChannelControls )上,数据datacontext的设置方式如下:

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

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

And on the xaml side : 在xaml方面:

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

But for some reason the property in cmixdata is not updated and always has the default value... 但是由于某些原因,cmixdata中的属性不会更新,并且始终具有默认值...

A UserControl should never have an "own" instance of a view model. UserControl永远不应具有视图模型的“自己的”实例。 Instead, it should have dependency properties that are bound to properties of an "external" view model. 相反,它应该具有绑定到“外部”视图模型的属性的依赖项属性。

Your ChannelsControl would declare a property like this (where I suppose that string is not an appropriate type for a count ): 您的ChannelsControl会声明一个这样的属性(我认为该string不是count的适当类型):

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); }
    }

    ...
}

In ChannelsControl's XAML, you would bind it like this: 在ChannelsControl的XAML中,您可以这样绑定它:

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

You would now use your UserControl like shown below, where you bind the Count property to a view model in the DataContext like this: 现在,您将使用如下所示的UserControl,将Count属性绑定到DataContext中的视图模型,如下所示:

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

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

You may now also use ChannelsControl in the ItemTemplate of an ItemsControl like this: 您现在还可以在ItemsControl的ItemTemplate中使用ChannelsControl,如下所示:

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

EDIT: Set the Window's DataContext to your view model singleton instance like this: 编辑:将Window的DataContext设置为您的视图模型单例实例,如下所示:

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

Or in code behind, in the MainWindow constructor: 或在后面的代码中,在MainWindow构造函数中:

DataContext = CMiXData.Instance;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM