Exemplo n.º 1
0
        /// <summary>
        /// Called when the <c>DataContext</c> property of the <see cref="TargetControl"/> has changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        public virtual void OnTargetControlDataContextChanged(object sender, DependencyPropertyValueChangedEventArgs e)
        {
            Log.Debug("DataContext of TargetControl '{0}' has changed to '{1}'", TargetControl.GetType().Name, ObjectToStringHelper.ToTypeString(TargetControl.DataContext));

            var dataContext = TargetControl.DataContext;

            if (dataContext == null)
            {
                return;
            }

            if (BindingHelper.IsSentinelObject(dataContext))
            {
                return;
            }

            if (ViewModel == dataContext)
            {
                return;
            }

            if (dataContext.GetType().IsAssignableFromEx(ViewModelType))
            {
                // Use the view model from the data context, probably set manually
                ViewModel = (IViewModel)dataContext;
            }
        }
        /// <summary>7
        /// Overridden OnPreRender method. Build data-options and add it into extender target as an data-options attribute.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (DesignMode)
            {
                return;
            }

            var dataOptions       = JQueryScriptBuilder.BuildDataOptionsAttribute(this);
            var targetControl     = this.TargetControl as WebControl;
            var htmlTargetControl = this.TargetControl as HtmlControl;

            if (targetControl == null && htmlTargetControl == null)
            {
                throw new Exception("Target control type must be WebControl or HtmlControl");
            }

            _targetControlType = TargetControl.GetType();

            TargetControl.Parent.SetRenderMethodDelegate(RenderTargetControl);
            var attrs = (targetControl != null)
                            ? (targetControl is CheckBox)
                ? (targetControl as CheckBox).InputAttributes
                                    : targetControl.Attributes
                            : (htmlTargetControl != null)
                                ? htmlTargetControl.Attributes
                                    : null;

            if (attrs != null)
            {
                attrs.Add(DataOptionPrefix + _attrControlName, dataOptions);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Called when the <see cref="TargetControl"/> has just been unloaded.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        /// <remarks>
        /// This method will call the <see cref="OnTargetControlUnloaded"/> which can be overriden for custom
        /// behavior. This method is required to protect from duplicate unloaded events.
        /// </remarks>
        private void OnTargetControlUnloadedInternal(object sender, UIEventArgs e)
        {
            // Don't do this again (another bug in WPF: OnLoaded is called more than OnUnloaded)
            if (!IsTargetControlLoaded)
            {
                return;
            }

            InvokeViewLoadEvent(ViewLoadStateEvent.Unloading);

            IsUnloading = true;

            //#if !NET
            //            _isFirstLayoutUpdatedAfterUnloadedEvent = true;
            //#endif

            Log.Debug("Target control '{0}' is unloaded", TargetControl.GetType().Name);

            var view = TargetControl as IView;

            if (view == null)
            {
                Log.Warning("Cannot unregister view '{0}' in the view manager because it does not implement IView", TargetControl.GetType().FullName);
            }
            else
            {
                _viewManager.UnregisterView(view);
            }

            IsTargetControlLoaded         = false;
            _isFirstValidationAfterLoaded = true;

            OnTargetControlUnloaded(sender, e);

            var targetControlAsIViewModelContainer = TargetControl as IViewModelContainer;

            if (targetControlAsIViewModelContainer != null)
            {
                ViewToViewModelMappingHelper.UninitializeViewToViewModelMappings(targetControlAsIViewModelContainer);
            }

            IsUnloading = false;

            InvokeViewLoadEvent(ViewLoadStateEvent.Unloaded);
        }
Exemplo n.º 4
0
 public void ResetDirtyFlag()
 {
     ScriptManager.RegisterClientScriptBlock(TargetControl, TargetControl.GetType(),
                                             string.Format("{0}_Values_Update", TargetControl.ClientID), string.Format("document.getElementById(\"{0}\").value = \"{1}\";",
                                                                                                                       string.Format("{0}_Values", TargetControl.ClientID), String.Join(",", GetValuesArray())), true);
 }
Exemplo n.º 5
0
        /// <summary>
        /// Subscribes to the parent view model container.
        /// </summary>
        private void SubscribeToParentViewModelContainer()
        {
            if (!SupportParentViewModelContainers)
            {
                return;
            }

            if (HasParentViewModelContainer)
            {
                return;
            }

            _parentViewModelContainer = FindParentByPredicate(TargetControl, o => o is IViewModelContainer) as IViewModelContainer;
            if (_parentViewModelContainer != null)
            {
                Log.Debug("Found the parent view model container '{0}' for '{1}'", _parentViewModelContainer.GetType().Name, TargetControl.GetType().Name);
            }
            else
            {
                Log.Debug("Couldn't find parent view model container");
            }

            if (_parentViewModelContainer != null)
            {
                _parentViewModelContainer.ViewModelChanged += OnParentViewModelContainerViewModelChanged;
                _parentViewModelContainer.ViewLoading      += OnParentViewModelContainerLoading;
                _parentViewModelContainer.ViewUnloading    += OnParentViewModelContainerUnloading;

                SubscribeToParentViewModel(_parentViewModelContainer.ViewModel);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Called when the <c>DataContext</c> property of the <see cref="TargetControl"/> has changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        public override void OnTargetControlDataContextChanged(object sender, DependencyPropertyValueChangedEventArgs e)
        {
            // Fix in WinRT to make sure inner grid is created
            if (_viewModelGrid == null)
            {
                if (TargetControl.Content != null)
                {
                    CreateViewModelGrid();
                }
                else
                {
                    Log.Error("Content of control '{0}' is not yet loaded, but the DataContext has changed. The control will bind directly to the DataContext instead of the view model", TargetControl.GetType().FullName);
                }
            }

            // Fix for CTL-307: DataContextChanged is invoked before Unloaded because Parent is set to null
            var targetControlParent = TargetControl.Parent;

            if (targetControlParent == null)
            {
                return;
            }

            base.OnTargetControlDataContextChanged(sender, e);

            var oldDataContext = e.OldValue;
            var dataContext    = e.NewValue;

            if (BindingHelper.IsSentinelObject(dataContext))
            {
                return;
            }

            if (oldDataContext != null)
            {
                ClearWarningsAndErrorsForObject(oldDataContext);
            }

            if (!IsUnloading)
            {
                UpdateDataContextToUseViewModel(dataContext);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Called when the <c>DataContext</c> property of the <see cref="TargetControl"/> has changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        public override void OnTargetControlDataContextChanged(object sender, DependencyPropertyValueChangedEventArgs e)
        {
            // Fix in WinRT to make sure inner grid is created
            if (_viewModelGrid == null)
            {
                if (TargetControl.Content != null)
                {
                    TargetControl.UnsubscribeFromDependencyProperty("Content", OnTargetControlContentChanged);

                    CreateViewModelGrid();
                }
                else
                {
                    Log.Error("Content of control '{0}' is not yet loaded, but the DataContext has changed. The control will bind directly to the DataContext instead of the view model", TargetControl.GetType().FullName);
                }
            }

            base.OnTargetControlDataContextChanged(sender, e);

            var oldDataContext = e.OldValue;
            var dataContext    = e.NewValue;

            if (BindingHelper.IsSentinelObject(dataContext))
            {
                return;
            }

            if (oldDataContext != null)
            {
                ClearWarningsAndErrorsForObject(oldDataContext);
            }

            UpdateDataContextToUseViewModel(dataContext);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Called when the <see cref="TargetControl"/> has just been loaded.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        /// <remarks>
        /// This method will call the <see cref="OnTargetControlLoaded"/> which can be overriden for custom
        /// behavior. This method is required to protect from duplicate loaded events.
        /// </remarks>
        private void OnTargetControlLoadedInternal(object sender, UIEventArgs e)
        {
            // Don't do this again (another bug in WPF: OnLoaded is called more than OnUnloaded)
            if (IsTargetControlLoaded)
            {
                return;
            }

            if (!CanControlBeLoaded)
            {
                Log.Debug("Received Loaded or LayoutUpdated, but CanControlBeLoaded is false thus not treating the control as loaded");
                return;
            }

            Log.Debug("Target control '{0}' is loaded", TargetControl.GetType().Name);

            InvokeViewLoadEvent(ViewLoadStateEvent.Loading);

            IsLoading = true;

            var view = TargetControl as IView;

            if (view == null)
            {
                Log.Warning("Cannot register view '{0}' in the view manager because it does not implement IView", TargetControl.GetType().FullName);
            }
            else
            {
                _viewManager.RegisterView(view);
            }

            IsTargetControlLoaded = true;

            OnTargetControlLoaded(sender, e);

#if !NET
            // According to the documentation, no visual tree is garantueed in the Loaded event of the user control.
            // However, as a solution the documentation says you need to manually call ApplyTemplate, so let's do that.
            // For more info, see http://msdn.microsoft.com/en-us/library/ms596558(vs.95)
            var targetControl = TargetControl as Control;
            if (targetControl != null)
            {
                (targetControl).ApplyTemplate();
            }
#endif

            var targetControlAsIViewModelContainer = TargetControl as IViewModelContainer;
            if (targetControlAsIViewModelContainer != null)
            {
                ViewToViewModelMappingHelper.InitializeViewToViewModelMappings(targetControlAsIViewModelContainer);
            }

            var dispatcher = TargetControl.Dispatcher;
            dispatcher.BeginInvokeIfRequired(() =>
            {
                if (ViewModel != null)
                {
                    // Initialize the view model. The view model itself is responsible to prevent double initialization
                    ViewModel.InitializeViewModel();

                    // Revalidate since the control already initialized the view model before the control
                    // was visible, therefore the WPF engine does not show warnings and errors
                    var viewModelAsViewModelBase = ViewModel as ViewModelBase;
                    if (viewModelAsViewModelBase != null)
                    {
                        viewModelAsViewModelBase.Validate(true, false);
                    }
                    else
                    {
                        ViewModel.ValidateViewModel(true, false);
                    }

                    _isFirstValidationAfterLoaded = true;
                }
            });

            IsLoading = false;

            InvokeViewLoadEvent(ViewLoadStateEvent.Loaded);
        }