WPF,绑定UserControl不起作用 [英] WPF, Binding UserControl Doesn't Work

查看:84
本文介绍了WPF,绑定UserControl不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我在wpf中创建了一个用户控件,并设置了DependencyProperty

 公共 部分  class  MyUserControl:UserControl
{
   公共 静态 只读 DependencyProperty DP = DependencyProperty.注册("  typeof ( 字符串), typeof (MyUserControl));
   公共 字符串文本
   {
      获取
      {
         返回  .MyTextBox.Text;
      }
      设置
      {
         MyTextBox.Text = ;
      }
   }
   公共 MyUserControl()
   {
      InitializeComponent();
   }
} 



问题是我无法在应用程序中绑定Text:

 <   my:MyUserControl    水平对齐  ="    名称  ="  myUserControl"  VerticalAlignment   顶部"  Width   ="    文本  ="  ">& gt;  


不起作用

但对于其他控件和作品也可以:

 <   dxe:TextEdit    水平对齐  ="    名称  ="  textEdit1"  VerticalAlignment   顶部"  Width   ="    文本  ="  / >  



pleese帮助我,我在Google上搜索了很多

解决方案

你好

我的解决方案不够标准,但是可以正常工作.我想您也可以找到一种标准方法;)

但是我的解决方案:

 公共 部分  class  MyUserControl:UserControl
{
   公共 只读 静态 DependencyProperty TextProperty = DependencyProperty.注册("  typeof ( 字符串), typeof (MyUserControl), PropertyMetadata(OnTextChanged));

   静态 无效 OnTextChanged(DependencyObject obj,
   DependencyPropertyChangedEventArgs args)
   {
      如果(TextChanged!= )
         TextChanged(obj);
   }

   公共 委托  void  TextChangeHandler(对象发​​送者);
   公共 静态 TextChangeHandler TextChanged;

   公共 字符串文本
   {
      获取 {返回(字符串) .GetValue(TextProperty);}
      设置 { .SetValue(TextProperty,);}
   }
   公共 MyUserControl()// 构造函数
   {
      InitializeComponent();
      TextChanged + =  TextChangeHandler((对象发​​送者)= > ; 
      {
         // 防止强制更改用户控件的其他实例
         如果( ==(((MyUserControl)sender)))
             .MyTextBox.Text =  .Text;
      });
      
       .MyTextBox.EditValueChanged + = 新的 EditValueChangedEventHandler((对象发​​送者,EditValueChangedEventArgs e)= > 
      {
          .Text = MyTextBox.Text;
      });
   }
} 



并且不要更改其他内容.

希望对您有所帮助!


据我所知,您不应该直接设置/获取值.代替此,您应该像这样使用GetValue/SetValue:

 获取 {返回( String ) this  .GetValue(DP); }
设置 { .SetValue(DP,); }


不确定要完成的操作.在WPF应用程序中,我总是在类中定义数据,如下所示:

 公共  class  Mydata:INotifyPropertyChanged
   {
       私有 字符串 userName;
       公共 字符串用户名
       {
           获取 {返回 userName; }
           设置
           {
                如果(userName!= )
                {
                      userName = ;
                      OnPropertyChanged(()=> this.UserName);
                }
           }
       }
       公共 无效 OnPropertyChange(字符串 propertyName)
        {
            如果(PropertyChanged!= )
                PropertyChanged( PropertyChangedEventArgs(propertyName));
        }
        公共 无效 OnPropertyChange< t> (表达式< t>> propertyExpression)
        {
            OnPropertyChange(propertyExpression.Name);
        }
        公共 事件 PropertyChangedEventHandler PropertyChanged;
   }
</  t  >  </  func  >  </  t  >  



在我的代码中的下一个背后,我有人口代码将该对象公开为公共属性:

 ....
公共 Mydata SomeData =  SomeData();
公共 MyUserControl()
{
      填充(SomeData);
}
...



终于在我的绑定中:

< my:myusercontrol horizo​​ntalalignment = "  name = "  verticalalignment = " 顶部" width =   74" text = "  xmlns:my =  #unknown"/> 



在WPF中,所有绑定属性都必须实现INotifyPropertyChanged,并且所有集合都必须封装在ObservableCollection中.


hi
I created a user control in wpf and set DependencyProperty

public partial class MyUserControl : UserControl
{
   public static readonly DependencyProperty DP = DependencyProperty.Register  ("Text", typeof(string), typeof(MyUserControl));
   public string Text
   {
      get
      {
         return this.MyTextBox.Text;
      }
      set
      {
         MyTextBox.Text = value;
      }
   }
   public MyUserControl()
   {
      InitializeComponent();
   }
}



the problem is I can not bind Text in my application:

<my:MyUserControl HorizontalAlignment="Left" Name="myUserControl" VerticalAlignment="Top" Width="74" Text="{Binding Path=UserName, Mode=TwoWay}"/>


Doesn''t work

but it is ok for other controls and works:

<dxe:TextEdit HorizontalAlignment="Left" Name="textEdit1" VerticalAlignment="Top" Width="73" Text="{Binding Path=UserName, Mode=TwoWay}" />



Pleese help me i googled a lot

解决方案

Hello

My solution is not adequately standard but it works. I guess there is also a standard way that you can find ;)

But my solution:

public partial class MyUserControl: UserControl
{
   public readonly static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MyUserControl), new PropertyMetadata(OnTextChanged));

   static void OnTextChanged(DependencyObject obj,
   DependencyPropertyChangedEventArgs args)
   {
      if (TextChanged != null)
         TextChanged(obj);
   }

   public delegate void TextChangeHandler(object sender);
   public static TextChangeHandler TextChanged;

   public string Text
   {
      get {return (String)this.GetValue(TextProperty);}
      set {this.SetValue(TextProperty, value);}
   }
   public MyUserControl()//Constructor
   {
      InitializeComponent();
      TextChanged += new TextChangeHandler((object sender) =>
      {
         //Prevent forcing changes to other instances of the user control
         if (this == ((MyUserControl)sender))
            this.MyTextBox.Text = this.Text;
      });
      
      this.MyTextBox.EditValueChanged += new EditValueChangedEventHandler((object sender, EditValueChangedEventArgs e) =>
      {
         this.Text = MyTextBox.Text;
      });
   }
}



And do not change the other things.

I hope it''ll help!


As far as I know you shouldn''t set/get value directly. Instead of this you should use GetValue/SetValue like this:

get { return (String)this.GetValue(DP); }
set { this.SetValue(DP, value); }


Not sure what exactly you want to accomplish. In my WPF applications I always have my data defined in classes as follows:

   public class Mydata:INotifyPropertyChanged
   {
       private string userName;
       public string UserName
       {
           get { return userName; }
           set
           {   
                if ( userName != value )
                {
                      userName = value;
                      OnPropertyChanged(()=>this.UserName);
                }
           }
       }
       public void OnPropertyChange ( string propertyName )
        {
            if ( PropertyChanged != null )
                PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
        }
        public void OnPropertyChange<t> ( Expression<func><t>> propertyExpression )
        {
            OnPropertyChange( propertyExpression.Name );
        }
        public event PropertyChangedEventHandler PropertyChanged;
   }
</t></func></t>



Next in my codeBehind I have population code to expose this object as a public property:

....
public Mydata SomeData = new SomeData();
public MyUserControl()
{
      Populate(SomeData);
}
...



Finally in my binding :

<my:myusercontrol horizontalalignment="Left" name="myUserControl" verticalalignment="Top" width="74" text="{Binding Path=SomeData.UserName, Mode=TwoWay}" xmlns:my="#unknown" />



In WPF all bound properties MUST implement INotifyPropertyChanged and all collections must be encapsulated in ObservableCollection''s.


这篇关于WPF,绑定UserControl不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆