2013-07-05 2 views
0

이것은 매우 어리석은 질문 일지 모르지만 코드에 어떤 문제가 있는지 찾으려고합니다.사용자 정의 컨트롤에서 종속성 속성 - WPF

버튼이있는 사용자 정의 컨트롤이 있습니다. DependencyProperty을 선언했습니다.이 컨트롤은 사용자 컨트롤 내부에있는 단추의 내용에 바인딩됩니다 (예, 이상합니다).

이제 기본 xaml 페이지에서이 사용자 정의 컨트롤의 인스턴스를 2 개 사용하고 종속성 속성이 내 ViewModel의 속성에 바인딩됩니다. 그러나 런타임에 바인딩이 실패합니다.

질문입니다 - 왜 작동하지 않습니까?

코드 :

<Window x:Class="WpfApplication2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfApplication2="clr-namespace:WpfApplication2" Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <WpfApplication2:UserControl1 NewContent="{Binding CanEnableOne}" Grid.Row="0"/> 
     <WpfApplication2:UserControl1 NewContent="{Binding CanEnableTwo}" Grid.Row="1"/> 
     <Button Grid.Row="2" Content="Enable Hello1" Click="OnClickedOne"/> 
     <Button Grid.Row="3" Content="Enable Hello2" Click="OnClickedTwo"/>   
    </Grid> 
</Window> 


public partial class MainWindow : Window 
{ 
    ViewModel vm = new ViewModel(); 
    Random r = new Random(); 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = vm; 
    } 

    private void OnClickedOne(object sender, RoutedEventArgs e) 
    { 
     vm.CanEnableOne = r.Next(1,100).ToString(); 
    } 

    private void OnClickedTwo(object sender, RoutedEventArgs e) 
    { 
     vm.CanEnableTwo = r.Next(1, 100).ToString(); 
    } 
} 

public class ViewModel : INotifyPropertyChanged 
{ 
    private string _canEnableOne; 
    public string CanEnableOne 
    { 
     get { return _canEnableOne; } 

     set 
     { 
      if (_canEnableOne == value) 
       return; 
      _canEnableOne = value; 
      InvokePropertyChanged("CanEnableOne"); 
     } 
    } 


    private string _canEnableTwo; 
    public string CanEnableTwo 
    { 
     get { return _canEnableTwo; } 

     set 
     { 
      if (_canEnableTwo == value) 
       return; 
      _canEnableTwo = value; 
      InvokePropertyChanged("CanEnableTwo"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void InvokePropertyChanged(string e) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(e)); 
    } 
} 


<UserControl x:Class="WpfApplication2.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> 
     <Button Content="{Binding NewContent}"></Button>  
    </Grid> 
</UserControl> 


public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    public static readonly DependencyProperty NewContentProperty = 
     DependencyProperty.RegisterAttached("NewContent", 
                typeof (string), 
                typeof (UserControl1), new PropertyMetadata(new PropertyChangedCallback(PropertyChanged))); 

    private static void PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     System.Diagnostics.Debug.WriteLine("Hello"); 
    } 

    public string NewContent 
    { 
     get { return (string)GetValue(NewContentProperty); } 
     set { SetValue(NewContentProperty, value); } 
    } 

} 

Error:System.Windows.Data Error: 39 : BindingExpression path error: 'NewContent' property not found on 'object' ''ViewModel' (HashCode=23172649)'. BindingExpression:Path=NewContent; DataItem='ViewModel' (HashCode=23172649); target element is 'Button' (Name=''); target property is 'Content' (type 'Object') 
System.Windows.Data Error: 39 : BindingExpression path error: 'NewContent' property not found on 'object' ''ViewModel' (HashCode=23172649)'. BindingExpression:Path=NewContent; DataItem='ViewModel' (HashCode=23172649); target element is 'Button' (Name=''); target property is 'Content' (type 'Object') 

답변

2

{Binding} 항상 속성의 소스로 DataContext을 현명 기본값으로, 기억하십시오. 따라서 코드가 작동하지 않는 이유는 NewContent이 ViewModel의 속성이 아닙니다.

당신은 바인딩, 당신의 UserControl을에,이 그것을 할 한 가지 방법입니다 귀하의 소스 변경하려면 :

<UserControl x:Class="WpfApplication2.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" 
      x:Name="myControl"> 
    <Grid> 
     <Button Content="{Binding ElementName=myControl, Path=NewContent></Button>  
    </Grid> 
</UserControl> 
관련 문제