Мне нужен универсальный UserControl, в котором я могу установить свойство, либо установив его значение в XAML напрямую, либо связав его с некоторым свойством модели.
Так же, как TextBlock, свойство Text работает.
Прямо сейчас у меня есть простой простой UserControl, у него есть одно свойство DependencyProperty TxT и привязанное к нему свойство TextBlock Text. Никакого другого кода нет.
Если я установлю TxT в XAML в главном окне, это не сработает, привязка сработает.
Если я добавлю PropertyChangedCallback к этому DependencyProperty, он также будет работать в XAML.
Итак, вопрос, обязательно ли иметь PropertyChangedCallback для каждого свойства, если я хочу иметь возможность установить его непосредственно в XAML?
Это неясно для меня, большинство не упоминают об этом, но это также вынуждает меня добавлять имена внутренних элементов управления для изменения их значения в PropertyChangedCallback.
Код ниже.
Можно ли это сделать другим способом?
MainWindow
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfAppDpBare" xmlns:Model="clr-namespace:WpfAppDpBare.Model" x:Class="WpfAppDpBare.MainWindow"
Background="CadetBlue"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<Model:MainModel/>
</Window.DataContext>
<Grid>
<local:UserControlSample TxT="DIRECT TXT" HorizontalAlignment="Center" VerticalAlignment="Center" Height="125" Width="125" Margin="10,34,659,262"/>
<TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="Direct" VerticalAlignment="Top" FontSize="14" FontWeight="Bold"/>
<TextBlock HorizontalAlignment="Left" Margin="203,10,0,0" TextWrapping="Wrap" Text="Binding" VerticalAlignment="Top" FontSize="14" FontWeight="Bold"/>
<local:UserControlSample DataContext="{Binding UCData}" HorizontalAlignment="Center" VerticalAlignment="Center" Height="125" Width="125" Margin="203,34,466,262"/>
</Grid>
public partial class MainWindow:Window {
public MainWindow() {
InitializeComponent();
}
}
UserControl
<UserControl x:Class="WpfAppDpBare.UserControlSample"
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"
xmlns:local="clr-namespace:WpfAppDpBare"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Background="White">
<Grid>
<TextBlock TextWrapping="Wrap" Text="{Binding TxT,FallbackValue=...,TargetNullValue=...}" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" FontWeight="Bold"/>
</Grid>
public partial class UserControlSample:UserControl {
public UserControlSample() {
InitializeComponent();
}
public string TxT {
get { return (string)GetValue(TxTProperty); }
set { SetValue(TxTProperty, value); }
}
// Using a DependencyProperty as the backing store for TxT. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TxTProperty =
DependencyProperty.Register("TxT", typeof(string), typeof(UserControlSample), new PropertyMetadata());
}
Модель
public class MainModel:ViewModelBase {
/// <summary>
/// The <see cref="UCData" /> property's name.
/// </summary>
public const string UCDataPropertyName = "UCData";
private UCModel uCModel = null;
/// <summary>
/// Sets and gets the UCData property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public UCModel UCData {
get {
return uCModel;
}
set {
if(uCModel == value) {
return;
}
uCModel = value;
RaisePropertyChanged(UCDataPropertyName);
}
}
public MainModel() {
UCData = new UCModel() { TxT = "BINDING TXT" };
}
}
public class UCModel:ViewModelBase {
/// <summary>
/// The <see cref="TxT" /> property's name.
/// </summary>
public const string TxTPropertyName = "TxT";
private string _TxT = null;
/// <summary>
/// Sets and gets the TxT property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string TxT {
get {
return _TxT;
}
set {
if(_TxT == value) {
return;
}
_TxT = value;
RaisePropertyChanged(TxTPropertyName);
}
}
}
Полный голый проект https://wetransfer.com/downloads/199f3db5d183e64cf9f20db4225d4c9820180702001102/f4f61b
![sample](https://i.imgur.com/C1JZICZ.png)
Как вы можете видеть в привязке проекта, прямой текст свойства отсутствует.
Я хочу, чтобы все это содержалось в usercontrol, поэтому я либо устанавливаю значение свойства usercontrol в xaml, либо привязываюсь к нему, без добавления в основное окно xaml или код.