2013-08-01 3 views
0

본질적으로 TextBox가있는 Label 인 UserControl을 만들고 싶습니다. 이제 TextBox.Text을 다른 값으로 바인딩 할 수 있기를 바래요.바인딩을위한 WPF UserControl을 올바르게 설정하는 방법

이 들어 나는 내 UserControl에 DependencyProperty를 만들었습니다. 그리고 새로 생성 된 DependencyProperty에 뭔가를 바인딩하려하지만 텍스트가 업데이트되지 않는 것 같습니다.

<UserControl x:Class="WpfApplication1.UserControl1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="48" d:DesignWidth="200"> 
<Grid> 
    <WrapPanel Height="48" HorizontalAlignment="Left" Name="wrapPanel1" VerticalAlignment="Top" Width="200"> 
     <Label Content="Label" Height="48" Name="label1" Width="100" /> 
     <TextBox Height="48" Name="textBox1" Width="100" /> 
    </WrapPanel> 
</Grid> 

을 그리고 내 UserControl1.xaml.cs은 다음과 같습니다 :

내 UserControl1.xaml은 다음과 같습니다 나는이 같은 UserControl을 사용하고

using System; 
using System.Collections.Generic; 
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.Diagnostics; 

namespace WpfApplication1 
{ 


    /// <summary> 
    /// Interaction logic for UserControl1.xaml 
    /// </summary> 
    public partial class UserControl1 : UserControl 
    { 
     private string value; 
     public string Value 
     { 
      get { return value; } 
      set 
      { 
       this.value = value; 
       textBox1.Text = value; 
       Trace.TraceInformation("value set in UserControl1"); 
      } 
     } 
     public static readonly DependencyProperty ValueProperty = 
      DependencyProperty.Register("Value", typeof(string), typeof(UserControl1)); 
     public UserControl1() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

:

<my:UserControl1 x:Name="userControl11" Value="{Binding Path=Name}" /> 

DataContext은 Name 속성이 있고이 속성에 대해 INotifyPropertyChanged를 구현하는 개체로 설정됩니다.

답변

1

TextBox의 텍스트와 UserControl 값을 잘못된 위치에 연결합니다. CLR 속성은 편의상 사용되지만 Bind Engine에서는 사용하지 않습니다.

<TextBox x:Name="textBox1" Text="{Binding Path=Value, ElementName=root}"/> 
+0

필자는 그것으로 인해 내 userControl이 업데이트되었지만 이제는 다른 버그가있는 것 같습니다. 'userControl11.TextBox1.Text'를 변경할 때마다 바운드 데이터가 다시 변경 될 때 업데이트되지 않습니다. TextBox에'Text = "{Binding Path = Value, ElementName = root, Mode = TwoWay}"'를 넣으려고했지만 그게 도움이되지 않습니다. – FlyingFoX

+1

그건 까다 롭습니다. BindingMode를 사용할 때 지정하지 않으면 기본적으로 사용자 지정 종속성 속성은 OneWay 바인딩입니다. 두 가지 선택 사항이 있습니다. 하나는 Mode = TwoWay로 지정하고, 두 번째는 FrameworkPropertyMetadata를 덮어 쓰면 기본 바인딩 모드가 TwoWay로 지정됩니다. –

2

당신은를 얻을 에 추가 논리 또는 코드를 추가하거나 할 수 없습니다 당신은 (당신이 사용자 정의 컨트롤의 이름이라는 루트를주고 가정)로, UserControl을의 가치에 텍스트 상자의 텍스트를 명시 적으로 XAML 또는 코드 숨김 바인딩해야합니다 종속성 속성을 래핑하는 속성에 대해 접근자를 설정합니다. 그것은 실행되지 않습니다.

이유는 WPF 디자이너가 실제로 DependencyProperty를 직접 사용하는 코드를 생성하기 때문입니다. get/set 속성은 코드에서 사용하면 편리합니다. DependencyProperty와 속성의 get/set에서 동일한 작업을 수행하기를 원하므로 관련 종속성 속성을 전달하는 동안 Get/Set 접근 자에서 GetValue 및 SetValue를 호출해야합니다.

은이 자습서를 참조하십시오 Dependency Properties Overview

2

Dependency Properties이 구현에서보세요. 아주 간단한 MVVM 디자인을 사용하여 데이터 바인딩을 얻습니다.

  • 당신은 그것이 해당 뷰 모델에 DataContext에있어 설정하여 UserControl을 (보기)가 : 기본적으로 이것은 무엇을하고 있는지입니다.
  • View의 TextBox가 해당 ViewModel의 public 속성에 바인딩됩니다.
  • INotifyPropertyChanged를 구현하면 ViewModel이 Text 속성의 값을 변경할 때마다 효과적으로 UI를 업데이트 할 수 있습니다.

이것은 임의의 수의 바인딩에 대해 반복되고 Lists, ObservableCollections, 정수와 같은 여러 유형에 적용될 수 있습니다.

보기

<UserControl x:Class="WpfApplication1.UserControl1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" d:DesignHeight="48" d:DesignWidth="200"> 
<Grid> 
    <WrapPanel Height="48" HorizontalAlignment="Left" Name="wrapPanel1" VerticalAlignment="Top" Width="200"> 
     <Label Content="Label" Height="48" Name="label1" Width="100" /> 
     <TextBox Height="48" Name="textBox1" Width="100" Text={Binding Text} /> 
    </WrapPanel> 
</Grid> 

보기 코드 숨김

namespace WpfApplication1 
{ 
    using System.Windows; 
    using System.Windows.Controls; 

    public partial class UserControl1: UserControl 
    { 
     public UserControl1() 
     { 
      DataContext = new UserControl1ViewModel(); 
      InitializeComponent(); 
     } 
    } 
} 

뷰 모델

namespace WpfApplication1 
{ 
    using System.Collections.ObjectModel; 
    using System.Windows.Controls; 

    class UserControl1ViewModel : INotifyPropertyChanged 
    { 
     // Ultimately, this field (text) would be moved to a model along with 
     // any other data fields for this view but for the sake of space, 
     // I've put it in the ViewModel. 
     private string text = ""; 
     public string Text 
     { 
      get { return text; } 
      set 
      { 
       text = value; 
       RaisePropertyChanged("Text"); 
      } 
     } 

     public MainWindowViewModel() 
     { 
      Text = "Hello!"; 
     } 

     // This is the implementation of INotifyPropertyChanged that is used 
     // to inform the UI of changes. 
     public event PropertyChangedEventHandler PropertyChanged; 
     protected void RaisePropertyChanged(string propertyName) 
     { 
      var handler = PropertyChanged; 
      if (handler != null) 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

행운을 빕니다!

관련 문제