代码之家  ›  专栏  ›  技术社区  ›  Maciek

WPF数据绑定问题

  •  1
  • Maciek  · 技术社区  · 15 年前

    我已经写了一个非常短的应用程序,其中我正在尝试实现以下目标:拥有 CheckBox 从代码更改其状态。我已经接通了 INotifyPropertyChanged 界面,并期待看到一些结果,但显然应用程序什么也不做。数据绑定有问题吗?

    Windows 1.CS

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Threading;
    
    namespace WpfTEST
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window, INotifyPropertyChanged
        {
            public Window1()
            {
                InitializeComponent();
                this.Loaded += new RoutedEventHandler(Window1_Loaded);
                this.PropertyChanged += new PropertyChangedEventHandler(Window1_PropertyChanged);
            }
    
            public bool Flag
            {
                get { return m_flag; }
                set
                {
                    m_flag = value; 
                    OnPropertyChanged("Flag");
                }
            }
    
            private bool m_flag = false;
    
            void Window1_Loaded(object sender, RoutedEventArgs e)
            {
                this.m_cbox.DataContext = this;
    
                for (int i = 0; i < 1000; i++)
                {
                    Flag = (i % 2 == 0);
                    Thread.Sleep(200);
                }
    
    
            }
    
            #region INotifyPropertyChanged Members
    
            public event PropertyChangedEventHandler PropertyChanged;
            public void OnPropertyChanged(string name)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
            void Window1_PropertyChanged(object sender, PropertyChangedEventArgs e)
            {
    
            }
    
            #endregion
        }
    }
    

    Windows 1.xAML

    <Window x:Class="WpfTEST.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300" x:Name="window">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.5*" />
                <ColumnDefinition Width="0.5*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="0.5*" />
                <RowDefinition Height="0.5*" />
            </Grid.RowDefinitions>
            <CheckBox x:Name="m_cbox" Content="Let's see what happens" Grid.Row="2" Grid.Column="2" Grid.RowSpan="1" Grid.ColumnSpan="1" IsChecked="{Binding Path=Flag, ElementName=window, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </Grid>
    </Window>
    
    2 回复  |  直到 13 年前
        1
  •  2
  •   Josh    15 年前

    我在代码中看到的唯一真正的问题是加载的睡眠循环。这会导致UI线程在循环期间没有响应,因为您将UI线程置于阻塞状态。

    有一种更好的方法可以测试您是否可以从代码中更改标志并触发绑定。在窗口中添加一个按钮,将一个单击处理程序连接到该按钮,然后在该单击处理程序中切换 Flag --我对您的原始代码进行了这些修改(并删除了睡眠循环),单击按钮以您希望的方式切换复选框的状态。

    <Window x:Class="WpfTEST.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300" x:Name="window">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.5*" />
                <ColumnDefinition Width="0.5*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="0.5*" />
                <RowDefinition Height="0.5*" />
            </Grid.RowDefinitions>
            <!-- I added this button: -->
            <Button Click="Button_Click" Grid.Row="0" Grid.Column="0"/>
            <CheckBox x:Name="m_cbox" Content="Let's see what happens" Grid.Row="2" Grid.Column="2" Grid.RowSpan="1" Grid.ColumnSpan="1" IsChecked="{Binding Path=Flag, ElementName=window, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </Grid>
    </Window>
    

    在代码背后:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Threading;
    
    namespace WpfTEST {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window, INotifyPropertyChanged {
            public Window1() {
                InitializeComponent();
                this.Loaded += new RoutedEventHandler(Window1_Loaded);
                this.PropertyChanged += new PropertyChangedEventHandler(Window1_PropertyChanged);
            }
    
            public bool Flag {
                get { return m_flag; }
                set {
                    m_flag = value;
                    OnPropertyChanged("Flag");
                }
            }
    
            private bool m_flag = false;
    
            void Window1_Loaded( object sender, RoutedEventArgs e ) {
                this.m_cbox.DataContext = this;
                Flag = false;
            }
    
            #region INotifyPropertyChanged Members
    
            public event PropertyChangedEventHandler PropertyChanged;
            public void OnPropertyChanged( string name ) {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
            void Window1_PropertyChanged( object sender, PropertyChangedEventArgs e ) {
    
            }
    
            #endregion
    
            private void Button_Click( object sender, RoutedEventArgs e ) {
                Flag = !Flag;
            }
        }
    }
    

    除了上述添加按钮及其单击处理程序并删除睡眠循环的修改之外,我没有对原始代码进行任何修改(尽管您可以对其进行一些简化)。

        2
  •  1
  •   Steve Psaltis    15 年前

    只有当Flag属性是依赖属性时,这才有效。为了以我能想到的最简单的方式实现这一目标,我将执行以下操作: 将绑定更改为:

    ischecked=“绑定路径=标志,模式=twoway”

    在您的代码后面的构造函数中,执行以下操作:

    dataContext=此;

    或在XAML中

    dataContext=“绑定relativesource=relativesource self”

    注意:如果要将DataContext设置为窗口,则标志不需要是依赖属性。

    推荐文章