Свойство зависимостей из пользовательского элемента управления — WPF

Вопрос:

Это может быть очень глупый вопрос, но я пытаюсь выяснить, что происходит с моим кодом.

У меня есть пользовательский элемент управления с кнопкой внутри него. У меня есть объявленный DependencyProperty, который я привязываю к содержимому кнопки внутри пользовательского элемента управления (да, это странно).

Теперь я использую 2 экземпляра этого пользовательского элемента управления на моей главной странице xaml, а свойство Dependency привязано к свойству в моей модели 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')

Лучший ответ:

Помните, что {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>

Оцените статью
TechArks.Ru
Добавить комментарий