Пользовательский элемент управления с привязкой к данным wpf - почему пользовательский элемент управления не обнаруживает изменения в моем источнике данных? - PullRequest
0 голосов
/ 08 февраля 2011

У меня есть пользовательский элемент управления и вид модели объекта.Свойство в модели представления привязано к пользовательскому элементу управления, и я вижу, что пользовательский элемент управления фактически получает поле от объекта модели представления - однако мой код обработчика (GeometryText.Set) не выполняется.Что я делаю не так?!

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

Спасибо за любой вклад,

Андерс, Дания

ComponentDrawing.xaml.cs

    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;
    using Rap1D.ServiceLayer.Interfaces.Services;
    using StructureMap;

    namespace Rap1D.Rap1D_WPF.Controls
    {
        /// <summary>
        /// Interaction logic for ComponentDrawing.xaml
        /// </summary>
        public partial class ComponentDrawing
        {
            public static DependencyProperty GeometryTextProperty =DependencyProperty.Register("GeometryText", typeof (string), typeof (ComponentDrawing), new FrameworkPropertyMetadata
                                                                                                    (
                                                                                                    "",
                                                                                                    FrameworkPropertyMetadataOptions
                                                                                                        .
                                                                                                        None));

            private Canvas _canvas;


            public ComponentDrawing()
            {
                InitializeComponent();
            }

            public string GeometryText
            {
                get { return ((string) GetValue(GeometryTextProperty)); }


                set
                {
                    SetValue(GeometryTextProperty, value);
                    ReadGeometryTextIntoDrawing(value);
                }
            }

            private void ReadGeometryTextIntoDrawing(string fileText)
            {
                // Allow control to be visible at design time without errors shown.
                // I.e. - don't execute code below at design time.
                if (DesignerProperties.GetIsInDesignMode(this))
                    return;

                // OK - we are a running application

                //if (_canvas != null)
                //    return;

                // OK - this is first time (-ish) we are running

                if (ActualWidth == 0)
                    return;

                // We have a valid screen to pain on

                var componentDrawingService = ObjectFactory.GetInstance<IComponentDrawingService>();

                //var commandTextProvider = ObjectFactory.GetInstance<ICommandTextProvider>();

                //var fileText = ((IViewModelBase) DataContext).GeometryText;

                // If getting the file text fails for some reason, just abort to avoid further problems.
                if (fileText == null)
                    return;

                var pg = componentDrawingService.GetDrawings(fileText, 0, ActualWidth, 0, ActualHeight);

                _canvas = new Canvas();

                foreach (var path in pg)
                {
                    _canvas.Children.Add(path);
                }

                Content = _canvas;
            }

            private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
            {
                //ReadGeometryTextIntoDrawing();
            }

            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                //ReadGeometryTextIntoDrawing();
            }

            private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                //ReadGeometryTextIntoDrawing();
            }
        }
    }

ComponentDrawing.xaml:

    <UserControl x:Class="Rap1D.Rap1D_WPF.Controls.ComponentDrawing" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" 
                 DataContextChanged="UserControl_DataContextChanged" Loaded="UserControl_Loaded" SizeChanged="UserControl_SizeChanged">
        <Grid Background="White">
            <Path Stroke="Black"></Path>
        </Grid>
    </UserControl>

Использование:

    <Controls:RadPane x:Class="Rap1D.Rap1D_WPF.Controls.ProductComponentDetails" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:Controls="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Docking" xmlns:Controls1="clr-namespace:Rap1D.Rap1D_WPF.Controls" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Header="{Binding DisplayName}">
        <Controls1:ComponentDrawing GeometryText="{Binding GeometryText}" />
    </Controls:RadPane>

просмотр объекта модели (реализация INotifyPropertyChanged):

    using System;
    using Microsoft.Practices.Prism.Events;
    using Rap1D.ExternalInterfaceWrappers.Interfaces;
    using Rap1D.ModelLayer.Interfaces.Adapters;
    using Rap1D.ModelLayer.Interfaces.Structure;
    using Rap1D.ServiceLayer.Interfaces.Adapters;
    using Rap1D.ServiceLayer.Interfaces.Providers;
    using Rap1D.ViewModelLayer.Interfaces;

    namespace Rap1D.ViewModelLayer.Implementations
    {
        public class ProductComponentViewModel : TreeViewItemViewModel, IProductComponentViewModel
        {

        ...

            public override string GeometryText
            {
                get
                {
                    var pentaResponse = _commandTextProvider.GetCommandText(ProductComponent);
                    return DateTime.Now.ToString()+ pentaResponse.Payload;
                }
            }

        ...

}}

1 Ответ

5 голосов
/ 08 февраля 2011

Установщики свойств зависимостей не вызываются, если они изменяются связыванием. Если вы хотите как-то отреагировать на изменение значения свойства зависимости, вы должны зарегистрировать обратный вызов в метаданных свойства:

http://msdn.microsoft.com/en-us/library/ms557294.aspx

что-то в этом роде (не уверен, что оно компилируется, дайте мне знать, если что-то не так):

public static DependencyProperty GeometryTextProperty =
     DependencyProperty.Register(... , new FrameworkPropertyMetadata(GeometryTextCallback));

public static void GeometryTextCallback(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
    // cast source to your type and invoke method from your setter
    ((ComponentDrawing)source)ReadGeometryTextIntoDrawing(value);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...