【问题标题】:Binding UserControl Property to an INotifyPropertyChanged View Model将 UserControl 属性绑定到 INotifyPropertyChanged 视图模型
【发布时间】:2012-09-19 13:18:59
【问题描述】:

此处给出的示例是我尝试实现的实际 UserControl 的简化,但它说明了结构并遇到了同样的问题。用户控件有一个 DependencyProperty Words,用于设置在用户控件 XAML 中定义的文本块的文本。

    public partial class MyControl : UserControl
    {
        public static readonly DependencyProperty WordsProperty = DependencyProperty.Register("Words", typeof(string), typeof(MyControl));
        public MyControl()
        {
            InitializeComponent();
        }
        public string Words
        {
            get { return (string)GetValue(WordsProperty); }
            set
            {
                m_TextBlock.Text = value;
                SetValue(WordsProperty, value);
            }

INotifyPropertyChanged ViewModelBase 类派生 ViewModel 被分配给 mainWindow DataContext。 ModelText 属性集调用 OnPropertyChanged。

class MainWindow : ViewModelBase
{
    private string m_ModelString;
    public string ModelText
    {
        get { return m_ModelString; }
        set
        {
            m_ModelString = value;
            base.OnPropertyChanged("ModelText");
        }
    }
}

在 MainWindow 中,XAML 绑定到 UserControl 和 TextBlock

 <Window x:Class="Binding.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="218" Width="266" xmlns:my="clr-namespace:Binding.View">
    <Grid>
        <my:MyControl Words="{Binding ModelText}" HorizontalAlignment="Left" Margin="39,29,0,0" x:Name="myControl1" VerticalAlignment="Top" Height="69" Width="179" Background="#FF96FF96" />
        <TextBlock Height="21" HorizontalAlignment="Left" Margin="59,116,0,0" Name="textBlock1" Text="{Binding ModelText}" VerticalAlignment="Top" Width="104" Background="Yellow" />
    </Grid>
</Window>

绑定适用于文本块,但不适用于用户控件。为什么 UserControl DependencyProperty 不能和 Control Properties 一样绑定?

【问题讨论】:

  • 您需要使用 {} 格式化代码块
  • 我确实尝试使用 {},但显然我做错了。很抱歉这是我的第一次尝试。

标签: .net wpf


【解决方案1】:

罪魁祸首是:

m_TextBlock.Text = value;

WPF 不直接使用由 DP 支持的属性。

如果您想在修改WordsProperty 时更新m_TextBlock.Text,请将该文本块绑定到Words,或使用UIPropertyMetadata 中的PropertyChangedCallback

 public static readonly DependencyProperty WordsProperty = 
         DependencyProperty.Register("Words", 
                                    typeof(string), 
                                    typeof(MyControl),
                                    new UIPRopertyMetadata(
                 new PropertyChangedCallback(
                     (dpo, dpce) => 
                     {
                         //Probably going to need to first cast dpo to MyControl
                         //And then assign its m_TextBlock property's text.
                         m_TextBlock.Text = dpce.NewValue as string;
                     })));

考虑dpo 发送者和dpce 事件参数。

【讨论】:

  • 感谢我尝试了 PropertyChangedCallback,它运行良好。
  • @user1683083 请考虑接受这个答案;)(点击答案左上角的勾号)
【解决方案2】:

我认为您应该通过绑定而不是 m_TextBlock.Text = value; 将文本分配给 UserControl 的文本框。

也许您可以在 UserControl Xaml 中使用这样的绑定:

    Text="{Binding Words
, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"

【讨论】:

  • 我可以在我给出的例子中看到你的观点。我想要实现的实际用户控件虽然更复杂。它使用画布使用平移和旋转变换在背景位图上渲染前景位图,但变换坐标来自模型。我计划向用户控件添加一个依赖属性,以允许模型通过提供一个包含 x,y,theta 的类来通知用户控件,然后使用此数据来修改转换,但我无法让绑定工作。
  • 我认为更好的办法是在用户控件中将 x,y,theta 属性设置为 DependencyProperties,然后在视图模型中对它们进行绑定。然后(就像狒狒说的)你可以订阅依赖属性的 OnPropertyChange 回调。
  • 我的想法是,您还可以在此视图 (xaml) 中使用绑定到同一个用户控件的依赖属性。
  • 是的,这听起来是为用户控件构建视图模型并单独绑定每个属性而不是编写视图的更好方法。
猜你喜欢
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多