UI不使用绑定XAML更新

本文关键字:XAML 更新 绑定 UI | 更新日期: 2023-09-27 18:17:29

我有一个问题,当UI不更新在变量的变化,这是绑定到控制属性。告诉我为什么。

1)我有一个类继承自UserControl和InotifyPropertyChanged

public class BindableControl:UserControl, INotifyPropertyChanged
    {
        #region Data
        private static readonly Dictionary<string, PropertyChangedEventArgs> eventArgCache;
        private const string ERROR_MSG = "{0} is not a public property of {1}";
        #endregion // Data
        #region Constructors
        static BindableControl()
        {
            eventArgCache = new Dictionary<string, PropertyChangedEventArgs>();
        }
        protected BindableControl()
        {
        }
        #endregion // Constructors
        #region Public Members
        /// <summary>
        /// Raised when a public property of this object is set.
        /// </summary>
        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// Returns an instance of PropertyChangedEventArgs for 
        /// the specified property name.
        /// </summary>
        /// <param name="propertyName">
        /// The name of the property to create event args for.
        /// </param>        
        public static PropertyChangedEventArgs
            GetPropertyChangedEventArgs(string propertyName)
        {
            if (String.IsNullOrEmpty(propertyName))
                throw new ArgumentException(
                    "propertyName cannot be null or empty.");
            PropertyChangedEventArgs args;
            // Get the event args from the cache, creating them
            // and adding to the cache if necessary.
            lock (typeof(BindableObject))
            {
                bool isCached = eventArgCache.ContainsKey(propertyName);
                if (!isCached)
                {
                    eventArgCache.Add(
                        propertyName,
                        new PropertyChangedEventArgs(propertyName));
                }
                args = eventArgCache[propertyName];
            }
            return args;
        }
        #endregion // Public Members
        #region Protected Members
        /// <summary>
        /// Derived classes can override this method to
        /// execute logic after a property is set. The 
        /// base implementation does nothing.
        /// </summary>
        /// <param name="propertyName">
        /// The property which was changed.
        /// </param>
        protected virtual void AfterPropertyChanged(string propertyName)
        {
        }
        /// <summary>
        /// Attempts to raise the PropertyChanged event, and 
        /// invokes the virtual AfterPropertyChanged method, 
        /// regardless of whether the event was raised or not.
        /// </summary>
        /// <param name="propertyName">
        /// The property which was changed.
        /// </param>
        protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
        {
            this.VerifyProperty(propertyName);
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                // Get the cached event args.
                PropertyChangedEventArgs args =
                    GetPropertyChangedEventArgs(propertyName);
                // Raise the PropertyChanged event.
                handler(this, args);
            }
            this.AfterPropertyChanged(propertyName);
        }
        #endregion
        #region Private Helpers
        [Conditional("DEBUG")]
        private void VerifyProperty(string propertyName)
        {
            Type type = this.GetType();
            // Look for a public property with the specified name.
            PropertyInfo propInfo = type.GetProperty(propertyName);
            if (propInfo == null)
            {
                // The property could not be found,
                // so alert the developer of the problem.
                string msg = string.Format(
                    ERROR_MSG,
                    propertyName,
                    type.FullName);
                Debug.Fail(msg);
            }
        }
        #endregion
    }

2)然后我有另一个类,它们每个都继承自BindableControl,像这样

public class CameraLocalization : BindableControl
    {
        public CameraLocalization()
        {
            headers = new CameraHeaders();
            toolTips = new CameraToolTips();
            SetRuLocal();
            //SetEnLocal();
        }
        private Language lang = SettingsManager.Language.ru_RU;
        private CameraHeaders headers;
        private CameraToolTips toolTips;
        public Language Lang
        {
            get { return lang; }
            set
            {
                lang = value;
                SetLocal();
                RaisePropertyChanged();
            }
        }
在XAML中,我将这个类链接为usercontrol,并像这样做绑定:
    xmlns:language ="clr-namespace:SettingsManager.Localization.Camera"
     <Grid>
           <language:CameraLocalization x:Name="Localization"></language:CameraLocalization>
<GroupBox Header="{Binding ElementName=Localization, Path=Headers.PositionGroupHeader, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"

4)从另一页我尝试改变语言:

    xmlns:language ="clr-namespace:SettingsManager.Localization.Camera"
<Grid Width="Auto">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Width="Auto" Margin="0,0,0,5">
            <language:CameraLocalization x:Name="Localization"></language:CameraLocalization>
<ComboBox ItemsSource="{Binding Source={StaticResource Language}}" Width="70" HorizontalAlignment="Left"
                                              SelectedValue="{Binding ElementName=Localization, Path=Lang, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></ComboBox>

什么也没发生。在调试模式下,我看到属性的值正在改变,但它们不会在UI上更新。这里的问题是什么?谁知道呢?

UI不使用绑定XAML更新

你的属性不应该在UI元素中声明(UserControl),这些不应该实现INotifyPropertyChanged。必须使用MVVM模式将UI与数据/逻辑分离。

你应该创建一个合适的ViewModel,并把你的属性和属性更改通知放在那里。