Как связать данные двух свойств зависимости, принадлежащих двум различным элементам управления - PullRequest
1 голос
/ 01 ноября 2011

В качестве альтернативы: Как подписаться на событие PropertyChanged, определенное INotifyPropertyChanged, через привязку данных двух свойств зависимости?

У меня есть два отдельных пользовательских элемента управления в моем главном окне.Один элемент управления содержит параметры, которые влияют на другой элемент управления, назовем его элементом управления отображением.Я хочу, чтобы элемент управления параметрами действовал как источник данных для элемента управления дисплеем, чтобы при изменении параметра в элементе управления параметрами элемент управления дисплеем прослушивал и реагировал соответствующим образом.

Для этого я создал класс, который реализует INotifyPropertyChanged, который хранит эти параметры и создал свойства зависимостей этого типа класса в обоих элементах управления.Я ожидал, что если я свяжу одно свойство элемента управления с другим, то получу желаемое поведение, но, к сожалению, я упускаю что-то важное, потому что элемент управления дисплеем не реагирует.

При более тщательном рассмотрении с помощью отладчика яобратите внимание, что мое событие PropertyChangedEventHandler PropertyChanged всегда было нулевым, когда свойство изменилось, и все, что я прочитал, указывает на то, что никто не слушает.

Поскольку элемент управления отображением создается в режиме реального времени, я должен программно создать привязку следующим образом:

var DispayControlValuesBinding = new Binding();
DispayControlValuesBinding.Source = DisplayControlsControl;
DispayControlValuesBinding.Path = new PropertyPath("DisplayControlValues");
DispayControlValuesBinding.Mode = BindingMode.OneWay;
DispayControlValuesBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
DispayControlValuesBinding.NotifyOnSourceUpdated = true;
//        
graph.SetBinding(Graph.DisplayControlValuesProperty, DisplayControlValuesBinding);

Оба элемента управления имеют свойство зависимости, которое называется DispayControlValues.Я пытаюсь привязать свойство DisplayControlValues ​​DisplayControlControl к свойству DisplayControlValues ​​графического элемента управления.

Когда приложение запускается, оно инициализирует элемент управления параметром, а затем по запросу пользователя создается программный элемент управления отображением и выполняется привязка.Затем я изменяю значение в элементе управления параметрами, это перехватывается классом параметров, который реализует интерфейс INotifyPropertyChanged, но поскольку никто не слушает, обработчик событий имеет значение null, и вот где я застрял.

Ваша помощьС благодарностью!

Вот более подробная информация по запросу:

У меня есть один пользовательский элемент управления, который предоставляет параметры, которые изменяют поведение другого элемента управления.Этот элемент управления имеет свойство зависимостей, которое содержит сведения о параметрах и реализует интерфейс INotifyPropertyChanged.

Вот класс:

public class ZoomGraphControlValues : INotifyPropertyChanged
{
    private bool _displayRaw;
    public bool DisplayRaw
    {
        get { return _displayRaw; }
        set 
        {
            _displayRaw = value;
            OnPropertyChanged(new PropertyChangedEventArgs("DisplayRaw"));
        }
    }

    private bool _enableFit;
    public bool EnableFit
    {
        get { return _enableFit; }
        set
        {
            _enableFit = value;
            OnPropertyChanged(new PropertyChangedEventArgs("EnableFit"));
        }
    }

    public ZoomGraphControlValues()
    {}

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, e);
    }
}

Вот свойство зависимостей:

public ZoomGraphControlValues ControlValues
    {
        get { return (ZoomGraphControlValues)GetValue(ControlValuesProperty); }
        set { SetValue(ControlValuesProperty, value); }
    }

    public static readonly DependencyProperty ControlValuesProperty =
        DependencyProperty.Register("ControlValues", typeof(ZoomGraphControlValues), typeof(ZoomGraphControls), new PropertyMetadata(null, OnControlValuesPropertyChanged));


    private static void OnControlValuesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var myObj = d as ZoomGraphControls;
        myObj.OnControlValuesPropertyChanged(e);
    }

    private void OnControlValuesPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        if (ControlValues != null)
        {
            IniValues();
        }
    }

Тогда у меня есть дисплей пользователя управления.Этот элемент управления также реализует свойство зависимостей того же типа, что и другой элемент управления, и я хочу, чтобы этот элемент управления был целью привязки, чтобы при изменении значений в элементе управления параметром этот элемент управления отражал изменения.

Вот свойство зависимости этого элемента управления:

    public ZoomGraphControlValues ZoomGraphControlValues
        {
            get { return (ZoomGraphControlValues)GetValue(ZoomGraphControlValuesProperty); }
            set { SetValue(ZoomGraphControlValuesProperty, value); }
        }

        public static readonly DependencyProperty ZoomGraphControlValuesProperty =
            DependencyProperty.Register("ZoomGraphControlValues", typeof(ZoomGraphControlValues), typeof(zoomGraph), new PropertyMetadata(null, OnZoomGraphControlValuesPropertyChanged));


        private static void OnZoomGraphControlValuesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var myObj = d as zoomGraph;
            myObj.OnZoomGraphControlValuesPropertyChanged(e);
        }

        private void OnZoomGraphControlValuesPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if (ZoomGraphControlValues != null)
            {

  // update the control with the new parameters
  ShowRawData(ZoomGraphControlValues.DisplayRaw);
                SetChartBehabiour();
            }
        }

Элемент управления Parameters инициализируется с начала цикла приложения.Элемент управления отображением создается в соответствии с запросом пользователя на вкладке, поэтому мне нужно создать элемент управления программным способом и, следовательно, привязку:

//create the tab and wire tab events
//…

//create a display control

var graph = new zoomGraph();

// initialize the parameters class

var zgcv = new ZoomGraphControlValues
{
  DisplayRaw = true,
  ChartBehaviour = ChartBehaviour.Zoom
};

//assign the parameters class to the parameters user control dependency property

ZoomGraphControlsControl.ControlValues = zgcv;

//create the binding of the parameter control to the display control by linking their respective dependency properties

var zoomGraphControlValuesBinding = new Binding();
zoomGraphControlValuesBinding.Source = ZoomGraphControlsControl;
zoomGraphControlValuesBinding.Path = new PropertyPath("ControlValues");
zoomGraphControlValuesBinding.Mode = BindingMode.TwoWay;
zoomGraphControlValuesBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
zoomGraphControlValuesBinding.NotifyOnSourceUpdated = true;
zoomGraphControlValuesBinding.NotifyOnTargetUpdated = true;

graph.SetBinding(zoomGraph.ZoomGraphControlValuesProperty, zoomGraphControlValuesBinding);

//…
// add the user control to a tab

Когда я изменяю параметр в элементе управления параметрами, я вижу, чтоон пытается запустить событие OnPropertyChanged, но всегда имеет значение null.Из-за этого мне кажется, что мне чего-то не хватает.

1 Ответ

0 голосов
/ 01 ноября 2011

Вы устанавливаете режим привязки на «OneWay», что означает, что модель представления никогда не будет обновляться при изменении значения в представлении.Измените режим привязки на «TwoWay» и попробуйте снова.

Кроме того, проверьте, не меняете ли вы полный экземпляр «DisplayControlValues» или только свойства этого класса, поскольку ваша привязка срабатывает только тогда, когда всяизменения экземпляра, а не его свойства.

Кроме того, имейте в виду, что вы можете связать свойства двух разных элементов управления с помощью свойства Binding.ElementName, что сделает ненужным создание модели представления,если в коде нет ничего, что вам нужно сделать, когда эти значения изменятся.

Если вы отправите больше кода и XAML, вам будет проще найти наиболее подходящий способ решения вашей проблемы.

...