Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# UI不使用绑定XAML更新_C#_Wpf_Xaml - Fatal编程技术网

C# UI不使用绑定XAML更新

C# UI不使用绑定XAML更新,c#,wpf,xaml,C#,Wpf,Xaml,我有一个问题,当用户界面不更新为变量的变化,这是绑定到控制属性。 帮我理解为什么 1) 我有一个从UserControl和InotifyPropertyChanged继承的类 public class BindableControl:UserControl, INotifyPropertyChanged { #region Data private static readonly Dictionary<string, PropertyChanged

我有一个问题,当用户界面不更新为变量的变化,这是绑定到控制属性。 帮我理解为什么

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
    }
3) 在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}"
xmlns:language=“clr命名空间:SettingsManager.Localization.Camera”

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


您应该创建一个适当的ViewModel,并将属性和属性更改通知放在那里。

好的,但我想不使用datacontext和资源绑定属性。如果我不使用userControl,我怎么能做到这一点呢?
但我想在不使用datacontext的情况下绑定属性,这是错误的。绑定是针对设置为UI元素的
DataContext
的任何对象进行解析的。这就是方法。不想这样做就像不想依靠空气呼吸一样。使用DataCOntext的坏处在于,在编译之前,您无法在VS编辑器中查看控件的ex.Header-这非常不舒服,并且使XAML代码导航变得困难。我已经通过datacontext完成了变量绑定,它工作得非常好,但您确定没有其他方法将类链接到XAML以在绑定中使用其属性吗?没有人关心Visual Studio设计器。如果确实需要,则必须为UserControls中的所有相关属性创建
dependencProperties
。您不能在任何
DependencyObject
派生的类中实现
INotifyPropertyChanged
    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}"
    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>