2016-03-24 4 views
1

У меня есть класс:Как связать UIElements в XAML?

class LinkedTextBox: TextBox 
{ 
    public TextBox TextBoxA { get; set; } 
    public TextBox TextBoxB { get; set; } 
} 

Say У меня есть два Textboxes:

<TextBox x:Name="txt1" /> 
    <TextBox x:Name="txt2" /> 

Как указать, что TextBoxes на моем Xaml?

Мои тесты:

(1) "TypeConverter для "TextBox". Не поддерживает преобразование из строки"

<local:LinkedTextBox TextBoxA="txt1" TextBoxB="txt2" /> 

(2) "A 'Связывание' не может быть установить на имущество «TextBoxA» типа «LinkedTextBox». А «Связывание» может быть установлен только на DependencyProperty из в DependencyObject. "

<local:LinkedTextBox 
     TextBoxA="{Binding ElementName=txt1}" 
     TextBoxB="{Binding ElementName=txt2}" 
     /> 

Я думаю, что есть очевидный способ сделать, но я не знаю, как ...

ответ

3

Право. Ваш второй пример правильный XAML, но он терпит неудачу, потому что TextBoxA и TextBoxB являются неправильным видом собственности. Целью Binding должна быть DependencyPropertyDependencyObject, как это говорится на жестяной банке. TextBox уже есть DependencyObject, и вы подклассифицируете его, чтобы часть была позабочена. И определение DependencyProperty тривиально.

Вы определили бы TextBoxA, как это, и TextBoxB также:

public class LinkedTextBox : TextBox 
{ 
    #region TextBoxA Property 
    public TextBox TextBoxA 
    { 
     get { return (TextBox)GetValue(TextBoxAProperty); } 
     set { SetValue(TextBoxAProperty, value); } 
    } 

    // Careful with the parameters you pass to Register() here. 
    public static readonly DependencyProperty TextBoxAProperty = 
     DependencyProperty.Register("TextBoxA", typeof(TextBox), typeof(LinkedTextBox), 
      new PropertyMetadata(null)); 
    #endregion TextBoxA Property 
} 

Но каково ваше намерение здесь? Что вы пытаетесь достичь? Очень вероятно, что вы можете сделать это, привязывая существующие свойства друг к другу обычным способом, без каких-либо из этих подклассов monkeyshines. Возможно, вам понадобится attached property, который является специализированным типом свойства зависимостей.

UPDATE

OP хочет, чтобы добавить визуальные элементы, иллюстрирующие отношения между текстовыми полями. Если вы хотите добавить визуальный оверлей, способ WPF «Сделать это» должен написать an Adorner. Поэтому вы должны написать какой-то TextBoxLinkingAdorner с TextBoxA и TextBoxB свойствами зависимостей и применить это к основному текстовому полю, которое в зависимости от ваших требований может даже не быть подклассом.

Возможно, вам понадобятся свойства зависимости, когда их значения изменяются; если да, то они больше похожи на это, предполагая Adorner подкласс имени TextBoxLinkerAdorner:

#region TextBoxA Property 
    public TextBox TextBoxA 
    { 
     get { return (TextBox)GetValue(TextBoxAProperty); } 
     set { SetValue(TextBoxAProperty, value); } 
    } 


    public static readonly DependencyProperty TextBoxAProperty = 
     DependencyProperty.Register("TextBoxA", typeof(TextBox), 
      typeof(TextBoxLinkerAdorner), 
      new FrameworkPropertyMetadata(null, 
        FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
        TextBoxA_PropertyChanged) 
         { DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); 

    protected static void TextBoxA_PropertyChanged(DependencyObject d, 
     DependencyPropertyChangedEventArgs e) 
    { 
     var obj = d as TextBoxLinkerAdorner; 
    } 
    #endregion TextBoxA Property 

Если все, что вы смотрите на на текстовые поля является их размер и местоположение, вы можете написать Adorner, которая связывает произвольное UIElements, а не только текстовые поля. Небо это предел! Если вы можете это увидеть, вы можете украсить его!

+0

Я буду «связывать» визуально текстовые поля (на самом деле рисовать линии), изменять визуальную картину с обеих сторон, возможно, менять позиции, а затем работать с текстом из обоих, обрабатывать и представлять результаты в LinkedTextBox. Я понимаю, что обычный способ напрямую связывает свойства, но мне нужно будет работать со множеством свойств, и я думаю, что действительно плохо связывает дюжину свойств, когда я могу напрямую связать основной UIElement. Я прочитаю о прикрепленных свойствах прямо сейчас, спасибо! –

+2

@ClickOk Ahhh, теперь я вижу, откуда вы. Вы можете взглянуть на [Adorners] (https://msdn.microsoft.com/en-us/library/ms743737 (v = vs.100) .aspx), которые являются способом WPFish (среди прочего) "наложение визуальных украшений на UIElement". Я бы подумал, что AdornerLayer будет принадлежать родительскому элементу TextBoxes. –