Пользовательский контроль данных Silverlight 3 Binding в xaml - PullRequest
2 голосов
/ 09 августа 2009

Я пытаюсь достичь чего-то, что концептуально довольно просто, но не может заставить его работать.

У меня есть класс с именем c1, в нем есть 2 свойства зависимостей: целое число I и строка S. Он реализует INotifiyPropertyChanged.

public class c1: INotifyPropertyChanged 
{
    private int i;
    public int I { get { return i; } set { i = value; if(PropertyChanged != null) PropertyChanged(this,new PropertyChangedEventArgs("I")); } }
    private string s;
    public string S { get { return s; } set { s = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("S")); } }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

На этот класс ссылается пользовательский элемент управления SUC Silverlight, который также реализует INotifiyPropertyChanged в качестве свойства зависимости C, с PropertyChangedCallback и т. Д. Как видно ниже.

public partial class SUC : UserControl, INotifyPropertyChanged
{

    public c1 C
    {
        get { return (c1)GetValue(CProperty); }
        set { SetValue(CProperty, value); }
    }
    public static readonly DependencyProperty CProperty =
        DependencyProperty.Register("C", typeof(c1), typeof(SUC), new PropertyMetadata(new c1(), new PropertyChangedCallback(c1Changed)));


    private static void c1Changed(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        SUC s = obj as SUC;
        if (s != null)
            s.CChanged((c1)e.NewValue);
    }

    public void CChanged(c1 c)
    {
        C = c;
        if(PropertyChanged!=null)
            PropertyChanged(this,new PropertyChangedEventArgs("C"));
    }
    public SUC()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private void bclick(object sender, RoutedEventArgs e)
    {
        C.S = C.S + " Clicked";
        MessageBox.Show(C.I.ToString() + " - " + C.S);
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

На моей главной странице, которая также реализует INotifiyPropertyChanged, у меня есть экземпляр c1 и SUC.

public partial class MainPage : UserControl, INotifyPropertyChanged
{


    public c1 MC
    {
        get { return (c1)GetValue(MCProperty); }
        set { SetValue(MCProperty, value); }
    }

    public static readonly DependencyProperty MCProperty =
        DependencyProperty.Register("MC", typeof(c1), typeof(MainPage), new PropertyMetadata(new c1()));


    private static void MCChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MainPage mp = d as MainPage;
        if (mp != null)
            mp.MCChanged();
    }

    public void MCChanged()
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("MC"));
    }

    public MainPage()
    {
        InitializeComponent();
        MC.S = "ssss";
        this.DataContext = this;
    }


    public event PropertyChangedEventHandler PropertyChanged;

}

Я хочу установить свойство C пользовательского элемента управления SUC через XAML. Вот так

local: SUC x: Name = "suc" C = "{Binding MC, Mode = TwoWay}"

Это хорошо работает в коде c #, но не в XAML. Причина, по которой он мне нужен в XAML, заключается в том, что я хочу связать коллекцию c1 с SUC в DataTemplate.

Буду признателен за любые рабочие примеры с загружаемым кодом.

Ответы [ 3 ]

1 голос
/ 09 августа 2009

Это простая небольшая ошибка в конструкторе класса SUC:

    public SUC()
    {
        InitializeComponent();
        this.DataContext = this; //this line shouldn't be here, delete and it will work
    }

Это означает, что DataContext элемента управления SUC сам по себе вместо класса MainPage, который необходим для привязки к MainPage.MC (класс SUC не имеет свойства MC).

Кроме того, и я понимаю, что большинство из них, возможно, вы просто пытались заставить его работать, но MC не обязательно должен быть DP, вам не нужно 'C = c;' в строке SUC, и я бы не стал использовать класс элемента управления MainPage в качестве класса datacontext, а создал бы другой класс для привязки DataContext.

0 голосов
/ 20 октября 2009

DataContext элементов управления UserControl может отличаться от самого UserControl или родительской «формы» UserControl (или родительской страницы UserControl).Вы должны установить привязку в коде позади.См. Этот пост для получения дополнительной информации: Привязка пользовательского свойства Silverlight UserControl

Кроме того, вы можете создать Silverlight Control вместо Silverlight UserControl

0 голосов
/ 09 августа 2009

Кажется, проблема в том, что вы устанавливаете DataContext для UserControl после , когда вы загружаете XAML. Либо установите его перед загрузкой XAML (т.е. до InitializeComponent), либо, что еще лучше, установите его в XAML следующим образом:

<local:MainPage ... DataContext="{Binding RelativeSource={RelativeSource Self}}">
    ....
</local:MainPage>

Привязка RelativeSource указывает, что DataContext вашего MainPage должно быть само по себе, что, по-видимому, является тем, что вы хотите. Это тогда устраняет назначение DataContext в коде позади, что всегда хорошо в WPF / Silverlight.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...