【问题标题】:Binding label to a variable将标签绑定到变量
【发布时间】:2014-07-06 03:11:49
【问题描述】:

我刚开始使用 WPF,我正在尝试设置局部变量和标签之间的绑定。基本上我想在局部变量更改时更新标签。我正在寻找解决方案,但他们都只是使用文本框作为源,而不仅仅是类变量,我什至不确定它是否以这种方式工作。所以这是我的代码。

public partial class MainWindow : Window
{
    int idCounter;

    public MainWindow()
    {
        InitializeComponent();


        Binding b = new Binding();
        b.Source = idCounter;
        b.Mode = BindingMode.OneWay;
        b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

        myLabel.SetBinding(Label.ContentProperty,b);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        idCounter++;
    }
}

按钮确实有效,idCounter 改变了值,但它没有在标签中更新,所以我猜绑定是错误的。有人可以告诉我有什么问题吗?谢谢

【问题讨论】:

    标签: c# wpf binding event-handling controls


    【解决方案1】:

    如果你将你的课程改成这个,你的代码就可以工作了……

      public partial class Window1 : Window, INotifyPropertyChanged
        {
            private int _idCounter;
            public int IdCounter
            {
                get { return _idCounter; }
                set
                {
                    if (value != _idCounter)
                    {
                        _idCounter = value;
                        OnPropertyChanged("IdCounter");
                    }
                }
            }
            public Window1()
            {
                InitializeComponent();
                myLabel.SetBinding(ContentProperty, new Binding("IdCounter"));
                DataContext = this;
            }
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                e.Handled = true;
                IdCounter++;
            }
            #region INotifyPropertyChanged Implementation
            public event PropertyChangedEventHandler PropertyChanged;
            protected virtual void OnPropertyChanged(string name)
            {
                var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(name));
                }
            }
            #endregion
        }
    

    您遇到的一些问题是......

    窗口本身应该实现 INotifyPropertyChanged 以便绑定引擎可以在其上放置一个耳朵。

    IdCounter 必须是公开的,并且上面有一个公开的 getter,以便绑定引擎可以“获取”它。

    您应该将 DataContext 设置为已声明 IdCounter 的任何类(在本例中为 MainWindow)。部分问题是绑定引擎没有 DataContext。

    BindingMode 设置是一个红鲱鱼,因为标签默认以这种方式绑定。

    UpdateSourceTrigger 是一个红鲱鱼,因为标签的内容没有更新源属性的机制。标签的内容不像文本框,用户可以在其中键入代码需要知道的内容。当您绑定到用户无法更改的内容时,忘记 UpdateSourceTrigger,重要的是 Target 属性。

    处理程序应该标记事件。这是一种很好的做法,不会影响绑定。

    绑定构造函数只需要路径。

    此代码将为您提供预期的结果;即,单击按钮时标签会更新。在 vs2013、.net 4.5 上检查、编译和执行。

    其他受访者表示您应该使用视图模型。我 100% 同意这一点,总的来说这是一件值得考虑的事情。

    【讨论】:

    • 从技术上讲,您的对象不是来自 INotifyPropertyChange 的 inherit,而是 implement 它。不错的答案。
    • @JohnathonSullinger,感谢您的精明头脑。我会编辑。助教
    【解决方案2】:

    您想使用属性来执行此操作,并实现INotifyPropertyChanged 以便在属性更改时更新label 的内容。

    这是一个使用简单ViewModel的示例

    xaml:

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:converters="clr-namespace:WpfApplication1"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <StackPanel>
            <Label Width="200" Height="50" Content="{Binding MyLabel}"/>
            <Button Height="30" Width="100" Content="Increment" Click="Button_Click" />
        </StackPanel>
    </Window>
    

    xaml.cs:

    namespace WpfApplication1
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            MainViewModel vm = new MainViewModel();
            public MainWindow()
            {
                InitializeComponent();
                this.DataContext = vm;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                vm.MyLabel += 1;
            }
        }
    }
    

    MainViewModel.cs:

    namespace WpfApplication1
    {
        public class MainViewModel : INotifyPropertyChanged
        {
            #region Members
            private int _myLabel;
            #endregion Members
    
            #region Properties
            public int MyLabel
            {
                get
                {
                    return _myLabel;
                }
                set
                {
                    _myLabel = value;
                    NotifyPropertyChanged("MyLabel");
                }
            }
    
            #endregion Properties
    
            public MainViewModel()
            {
            }
    
            #region INotifyPropertyChanged
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(String propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion
        }
    }
    

    注意:理想情况下,您希望为 Button 使用 Command 而不是 Click 事件处理程序

    【讨论】:

      【解决方案3】:
      1. 您不能绑定到私有的东西或字段,因此将其转换为公共属性。您可以找到更多关于什么是有效的绑定源here
      2. 如果您希望 UI 获取对属性的更改,您应该实现 INotifyPropertyChanged 接口并在每次属性值更改时引发事件。所以idCounter 应该看起来更像这样:

        private int _idCounter;
        
        public int idCounter
        {
            get { return _idCounter; }
            set
            {
                if (_idCounter != value)
                {
                    _idCounter = value;
                    OnPropertyChanged("idCounter");
                }
            }
        }
        
      3. 当您创建与属性的绑定时,您使用Path

      4. 绑定在绑定上下文中工作,因此您需要指定从何处获取此Path。最简单的方法是设置DataContext。因此,在您的情况下,初始化应该更像这样:

        Binding b = new Binding("idCounter");
        b.Mode = BindingMode.OneWay;
        b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        
        myLabel.SetBinding(Label.ContentProperty, b);
        DataContext = this;
        
      5. 正如@d.moncada 在他的回答中建议的那样,您应该创建专用的视图模型

      【讨论】:

        猜你喜欢
        • 2011-03-09
        • 2012-01-12
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 2015-06-30
        • 1970-01-01
        • 2020-02-23
        • 1970-01-01
        相关资源
        最近更新 更多