2013-09-03 2 views
1

Я в основном имеют те же проблемы, как этот парень здесь: Error: " 'Subjects' property was already registered by 'Period' " is raised when more than one control is placed on the formИспользование зависимостей свойств с несколькими экземплярами

Основное различие между нами в том, что я хочу подписаться на событие, которое имеет доступ к локальному экземпляру при изменении XAML недвижимость.

Так у меня есть UserControl:

public partial class BoardSquare : UserControl 
{ 
    public BoardSquare() 
    { 
     InitializeComponent(); 
     Location = new BoardLocation(Int32.MinValue, Int32.MinValue); 

     XPositionProperty = 
      DependencyProperty.Register("XPosition", typeof(int), 
      typeof(BoardSquare), new PropertyMetadata(
       new PropertyChangedCallback((value, args) => 
       { 
        Location.X = (int)args.NewValue; 
        resetBackgroundColorToPosition(); 
       }))); 
     YPositionProperty= 
      DependencyProperty.Register("YPosition", typeof(int), 
      typeof(BoardSquare), new PropertyMetadata(
       new PropertyChangedCallback((value, args)=> 
       { 
        Location.Y = (int)args.NewValue; 
        resetBackgroundColorToPosition(); 
       }))); 
    } 

    private void resetBackgroundColorToPosition() 
    { 
     this.Background = (Brush)(new ColorEnumToBrushesConverter()).Convert(Location.GetSquareColor(), typeof(BlackWhiteColor), null, null); 
    } 

    public readonly DependencyProperty XPositionProperty; 
    public readonly DependencyProperty YPositionProperty; 

    public int XPosition 
    { 
     get 
     { 
      return (int)GetValue(XPositionProperty); 
     } 
     set 
     { 
      SetValue(XPositionProperty, value); 
     } 
    } 

    public int YPosition 
    { 
     get 
     { 
      return (int)GetValue(YPositionProperty); 
     } 
     set 
     { 
      SetValue(YPositionProperty, value); 
     } 
    } 

    public BoardLocation Location { get; set; } 
} 

Вот мой XAML:

<local:BoardSquare Grid.Column="3" Grid.Row="0" XPosition="3" YPosition="0"/> 
<local:BoardSquare Grid.Column="4" Grid.Row="0" XPosition="4" YPosition="0"/> 

Из того, что я понимаю, решение сделать XPositionProperty статическим, а затем зарегистрировать его в статическом конструкторе. Моя проблема тогда в том, что я не могу получить доступ к локальному экземпляру класса, когда происходит событие PropertyChangeCallback.

Как я могу установить свойство в XAML и все еще получить событие с изменением свойства on в коде C#?

Есть ли лучшее решение, чем свойства зависимостей?


Ниже приведен рабочий код BoardSquare после того, как я выполнил ответ.

public partial class BoardSquare : UserControl 
{ 
    static BoardSquare() 
    { 
     XPositionProperty = 
      DependencyProperty.Register("XPosition", typeof(int), 
      typeof(BoardSquare), new PropertyMetadata(
       new PropertyChangedCallback((objectInstance, args) => 
       { 
        BoardSquare boardSquare = (BoardSquare)objectInstance; 
        boardSquare.Location.X = (int)args.NewValue; 
        boardSquare.resetBackgroundColorToPosition(); 
       }))); 
     YPositionProperty = 
      DependencyProperty.Register("YPosition", typeof(int), 
      typeof(BoardSquare), new PropertyMetadata(
       new PropertyChangedCallback((objectInstance, args) => 
       { 
        BoardSquare boardSquare = (BoardSquare)objectInstance; 
        boardSquare.Location.Y = (int)args.NewValue; 
        boardSquare.resetBackgroundColorToPosition(); 
       }))); 
    } 

    public BoardSquare() 
    { 
     InitializeComponent(); 
     Location = new BoardLocation(Int32.MinValue, Int32.MinValue); 


    } 

    private void resetBackgroundColorToPosition() 
    { 
     this.Background = (Brush)(new ColorEnumToBrushesConverter()).Convert(Location.GetSquareColor(), typeof(BlackWhiteColor), null, null); 
    } 

    public static readonly DependencyProperty XPositionProperty; 
    public static readonly DependencyProperty YPositionProperty; 

    public int XPosition 
    { 
     get 
     { 
      return (int)GetValue(XPositionProperty); 
     } 
     set 
     { 
      SetValue(XPositionProperty, value); 
     } 
    } 

    public int YPosition 
    { 
     get 
     { 
      return (int)GetValue(YPositionProperty); 
     } 
     set 
     { 
      SetValue(YPositionProperty, value); 
     } 
    } 

    public BoardLocation Location { get; set; } 
} 

ответ

1

первый аргумент из PropertyChangedCallback является локальный экземпляр (кстати. Вам лучше назвать это OBJ чем значение, чтобы избежать путаницы). Вы должны наложить это DependencyObject на BoardSquare и все.

public static readonly DependencyProperty XPositionProperty = 
    DependencyProperty.Register("XPosition", typeof(int), typeof(BoardSquare), 
           new PropertyMetadata(new PropertyChangedCallback((obj, args) => { 
            BoardSquare bs = obj as BoardSquare; 
            bs.Location.X = (int)args.NewValue; 
            bs.resetBackgroundColorToPosition(); 
           }))); 
+0

Очень приятно, я чувствую себя глупо, что не понимаю, что obj был моим примером. Большое спасибо. –

0

Если я правильно понял ваш вопрос, вы пытаетесь переопределить уже свойство сертификата WPF со своим собственным. Я не думаю, что это необходимо здесь. Если XPosition уже является свойством сертификата WPF, все, что вам нужно сделать, это создать свойство в вашем usercontrol с помощью getter/setter с помощью setter, вызывающего INotifypropertychanged. вам не нужно свойство зависимости в этом случае, если вы хотите только одно и то же имя, но вести себя по-другому, и почему вы этого хотите?

+0

Я не пытаюсь переопределить существующее имущество. XPosition и YPosition можно назвать чем-то другим. Без свойства зависимости я не могу присваивать значения им в XAML. Я бы предпочел держаться подальше от сеттера, потому что вещи выглядят чище, но я могу быть принужден к этому маршруту. –

Смежные вопросы