OK je sais. Cela a été demandé un million de fois, mais je ne comprends toujours pas. Désolé.
La tâche: implémenter la propriété de dépendance la plus simple de tous les temps, qui peut être utilisée dans xaml comme ça:
<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>
Je pense que this réponse est assez proche. Pour une meilleure lisibilité, je copie tout mon code ici (principalement à partir de cette réponse ci-dessus).
<UserControl x:Class="Test.UserControls.MyUserControl1"
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"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<!-- Text is being bound to outward representative property;
Note the DataContext of the UserControl -->
<TextBox Text="{Binding MyTextProperty}"/>
</Grid>
</UserControl>
et
public partial class MyUserControl1 : UserControl
{
// The dependency property which will be accessible on the UserControl
public static readonly DependencyProperty MyTextPropertyProperty =
DependencyProperty.Register("MyTextProperty", typeof(string), typeof(MyUserControl1), new UIPropertyMetadata(String.Empty));
public string MyTextProperty
{
get { return (string)GetValue(MyTextPropertyProperty); }
set { SetValue(MyTextPropertyProperty, value); }
}
public MyUserControl1()
{
InitializeComponent();
}
}
Et voici mon MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml" xmlns:uc="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Vertical">
<uc:MyUserControl1 MyTextProperty="my text goes here"/>
<Button Click="ButtonBase_OnClick" Content="click"/>
</StackPanel>
</Window>
Jusqu'à présent, tout fonctionne. Cependant, je trouve cela tout à fait inutile. Ce dont j'ai besoin c'est
<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>
et pouvoir changer cela en définissant un DataContext
(comme vous le faites habituellement dans MVVM)
Je remplace donc la ligne comme ci-dessus et ajoute mon code derrière comme suit:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
Text = "Initial Text";
DataContext = this;
}
private string _Text;
public string Text
{
get { return _Text; }
set
{
if (value != _Text)
{
_Text = value;
NotifyPropertyChanged("Text");
}
}
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
Text = "clicked";
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
Ni le "Texte initial" ni le "cliqué" ne sont affichés ... jamais. Ma question est donc de savoir comment mettre en œuvre un département. propriété à utiliser correctement avec
<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>
? Merci pour votre aide.
La propriété Text
est située sur le DataContext
du MainWindow et non du UserControl.
Alors changez cette ligne <uc:MyUserControl1 MyTextProperty="{Binding Text}"/>
dans ceci:
<uc:MyUserControl1 MyTextProperty="{Binding Text, ElementName=MyMainWindow}"/>
Ce qui indiquera à la liaison que vous parlez de l'élément texte situé dans votre fenêtre principale. Bien sûr, puisque dans cet exemple j'ai utilisé ElementName
, vous allez vouloir nom votre fenêtre MyMainWindow ...
Alors ajoutez ceci à votre MainWindow:
<Window Name="MyMainWindow" ..... />
Si vous préférez ne pas nommer votre fenêtre, vous pouvez utiliser la liaison RelativeSource FindAncestor comme ceci:
<wpfApplication6:MyUserControl1 MyTextProperty="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"/>
Dans les deux cas, vous demandez de trouver la propriété nommée 'Text' dans le DataContext de la fenêtre.