2014-09-23 13 views
10

Ich habe eine Abhängigkeitseigenschaft in der Usercontrol, aber jedoch Veränderungen in der Usercontrol war nicht auf die AnsichtsmodellWPF Usercontrol Zweiweg Bindung Abhängigkeitseigenschaft

Usercontrol

<UserControl x:Class="DPsample.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="300" d:DesignWidth="300"> 
<Grid> 
    <TextBox x:Name="txtName"></TextBox> 
</Grid> 

UserControl.cs benachrichtigt

/// <summary> 
/// Interaction logic for UserControl1.xaml 
/// </summary> 
public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    #region SampleProperty 

    public static readonly DependencyProperty SamplePropertyProperty 
              = DependencyProperty.Register("SampleProperty", 
              typeof(string), 
              typeof(UserControl1), 
              new PropertyMetadata(OnSamplePropertyChanged)); 


    public string SampleProperty 
    { 
     get { return (string)GetValue(SamplePropertyProperty); } 
     set { SetValue(SamplePropertyProperty, value); } 
    } 


    static void OnSamplePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     (obj as UserControl1).OnSamplePropertyChanged(e); 
    } 
    private void OnSamplePropertyChanged(DependencyPropertyChangedEventArgs e) 
    { 
     string SamplePropertyNewValue = (string)e.NewValue; 

     txtName.Text = SamplePropertyNewValue; 
    } 

    #endregion 
} 

Hauptfenster

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:DPsample" x:Class="DPsample.MainWindow" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 

    <local:UserControl1 SampleProperty="{Binding SampleText,Mode=TwoWay}" HorizontalAlignment="Left" Margin="76,89,0,0" VerticalAlignment="Top" Width="99"/> 
    <Button Content="Show" HorizontalAlignment="Left" Margin="76,125,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> 

</Grid> 

MainWindow.cs

public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = new MainViewModel(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     var item = this.DataContext as MainViewModel; 
     MessageBox.Show(item.SampleText.ToString()); 
    } 

MainViewModel.cs

public class MainViewModel : NotifyViewModelBase 
{ 
    public MainViewModel() 
    { 
     this.SampleText = "test";   
    } 

    private string _sampleText; 
    public string SampleText 
    { 
     get { return _sampleText; } 
     set { _sampleText = value; OnPropertyChanged("SampleText"); } 
    } 
} 
+0

Sie haben nichts codiert, das Änderungen der 'TextBox.Text' -Eigenschaft an' SampleProperty' übergibt. Sie sollten dort auch eine Bindung verwenden, mit 'RelativeSource = {RelativeSource AncestorType = UserControl}'. – Clemens

+0

@Clemens muss ich das viewmodel für die usercontrol verwenden? –

+0

Nicht in diesem Fall. Das UserControl kann jedoch auch direkt an die Eigenschaft 'SampleText' des Ansichtsmodells gebunden werden. Dann gäbe es überhaupt keine Notwendigkeit für "SampleProperty". – Clemens

Antwort

26

Bind die TextBox.Text Eigenschaft in dem Usercontrol auf seine SampleProperty wie folgt aus:

<TextBox Text="{Binding SampleProperty, 
         RelativeSource={RelativeSource AncestorType=UserControl}}"/> 

Jetzt können Sie einfach Ihren OnSamplePropertyChanged Rückruf entfernen.


Sie auch SampleProperty registrieren könnte wie folgt Zweiweg-standardmäßig zu binden:

public static readonly DependencyProperty 
    SamplePropertyProperty = DependencyProperty.Register(
     "SampleProperty", typeof(string), typeof(UserControl1), 
     new FrameworkPropertyMetadata(
      null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 
+1

Ich kann nicht glauben, dass ich so viele Tutorials und Beispiele zu benutzerdefinierten UserControls und DependencyProperties gelesen habe und nicht die FrameworkPropertyMetadata erwähnt, die die Übergabe des Werts an das Modell löst. Toller Job Mann! –

2

Ich kenne diese eine alte, beantwortete Frage, aber für mehr einfache Möglichkeit, es zu tun, können Sie binden die Eigenschaft wie folgt:
Erste diese Eigenschaft in dem Usercontrol x:Name (zB x:Name="MyUC" Dann, um die Bindung ändern:

<TextBox Text="{Binding ElementName=MyUC, Path=SampleProperty}"/> 

Ich sah diese Lösung irgendwo, aber erinnere mich nicht wo. Ich hoffe, es hilft.