在Windows Phone中将MVVM绑定到自定义控件

3

我是一个有用的助手,可以为您进行文本翻译。

我有以下简单的自定义控件,为 Windows Phone 应用程序定义。该控件的 XAML 如下:

<UserControl x:Class="PhoneApp1.MyControl"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
         d:DesignHeight="480"
         d:DesignWidth="480"
         DataContext="{Binding RelativeSource={RelativeSource Self}}">

<Grid x:Name="LayoutRoot">
    <TextBlock Text="{Binding MyLabel}" />
</Grid>

此外,用户控件具有以下依赖属性:
public partial class MyControl : UserControl
{
    public MyControl()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty MyLabelProperty =
        DependencyProperty.Register("MyLabel", typeof (string), typeof (MyControl), new PropertyMetadata(default(string)));

    public string MyLabel
    {
        get { return (string) GetValue(MyLabelProperty); }
        set { SetValue(MyLabelProperty, value); }
    }
}

现在的问题是,当我尝试将其数据绑定到已创建的视图模型时,什么也没有发生。不同代码项如下:

public class MyControlViewModel : ViewModelBase
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value;
        RaisePropertyChanged(() => Name);}
    }
}

在App.xaml中声明视图模型
<Application.Resources>
    <PhoneApp1:MyControlViewModel x:Key="MCVM" />
</Application.Resources>

控件的MainPage.xaml声明

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <PhoneApp1:MyControl  x:Name="testControl" DataContext="{StaticResource MCVM}" MyLabel="{Binding Path=MyLabel}" />            
    </Grid>

然而,如果我尝试按照以下方式将其数据绑定到其他UI元素,似乎可以工作?
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <PhoneApp1:MyControl  x:Name="testControl" MyLabel="{Binding ElementName=Button, Path=Content}" />
        <Button Click="Button_Click" x:Name="Button" Content="Click" />
    </Grid>

我一直在尝试使这个简单的场景起作用,但是我认为我漏掉了一些愚蠢的东西?

非常感谢任何帮助


你想在TextBlock中显示MyLabel.Text吗? - sll
1个回答

5

这是WPF;我不确定这是否完全类似于WP7银光;我提供更多细节来帮助你理解正在发生的事情,以便你可以研究出一个适当的解决方案,如果我的两个选项不可用。

默认情况下,绑定会在xaml文件的根元素的DataContext中进行连接(无论是Window还是UserControl)。这意味着

<TextBlock Text="{Binding MyLabel}" />

尝试绑定到 DataContext。因此,您试图绑定的属性是

MyControl.DataContext.MyLabel

您需要改为绑定到以下内容:

MyControl.MyLabel

因此,您必须将绑定重新基于视觉树中希望进行绑定的元素,即 MyControl 类。有几种方法可以做到这一点...

<TextBlock Text="{Binding MyLabel, 
                 RelativeSource={RelativeSource FindAncestor,
                                                AncestorType=UserControl}" />

使用递归遍历树结构是一种常见的方法,但这可能会对性能造成影响。我认为更简单且推荐的做法是:

<UserControl x:Class="PhoneApp1.MyControl"
             x:Name="root"
             x:SnipAttributesBecauseThisIsAnExample="true">
    <TextBlock Text="{Binding MyLabel, ElementName=root}" />
</UserControl>

给你的UserControl起一个名字,然后使用ElementName将绑定重新基于可视树的根。

我会略过其他更怪异的实现方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接