【发布时间】:2018-07-04 11:49:24
【问题描述】:
我想要一个通用的 UserControl,我可以通过直接在 XAML 中设置其值或将其绑定到某个模型属性来设置属性。
就像 TextBlock Text 属性一样。
现在我只有一个简单的 UserControl,它有一个 DependencyProperty TxT 和一个绑定到它的 TextBlock Text 属性。没有其他代码。
如果我在主窗口的 XAML 中设置 TxT,它将不起作用,绑定有效。
如果我将 PropertyChangedCallback 添加到该 DependencyProperty 它也适用于 XAML。
所以问题是,如果我希望能够直接在 XAML 中设置每个属性,是否必须为每个属性设置 PropertyChangedCallback?
这对我来说不是很清楚,大多数人都没有提到它,但这也迫使我添加内部控件名称以更改它们在 PropertyChangedCallback 中的值。
代码如下。
可以用其他方法吗?
主窗口
<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 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
正如您在项目绑定工作中看到的,直接属性文本不是。
我希望它全部包含在用户控件中,所以我要么在 xaml 中设置用户控件属性值,要么绑定到它,而不在主窗口 xaml 或代码中添加其他内容。
【问题讨论】:
-
@ASh 和stackoverflow.com/questions/4368808/…基本一样,是你能做的最简单的代码,如果我的描述不够我可以提供一个裸项目。
-
那个解决了。如果你的不工作,那么smth是不同的
-
另一个stackoverflow.com/questions/50835495/… 帖子我展示了使用自定义依赖属性创建用户自定义控件以及如何在 xaml 中进行设置。通过标准绑定您尝试绑定到的模型,文本值可以/也应该完全有效...看看该链接是否有助于理解这些步骤...
-
显示您的代码,否则我们无法帮助您。也就是说,“如果我希望能够直接在 XAML 中设置它,是否必须为每个属性设置 PropertyChangedCallback?” - 不,绝对不是。有没有这样的回调并不重要。