用户控件的依赖属性不绑定

时间:2014-02-01 20:03:35

标签: c# wpf windows-phone-8

我有依赖属性的用户控件。当我尝试在Windows中绑定它时,它不起作用。但是,当我更改绑定到普通参数(在这种情况下,为真)时,它正在工作。我需要做些什么来使我的绑定工作?也许是DataContext的东西?这是我的代码:

第一个用户控件的xaml:

<UserControl x:Class="DPTest.CustomUserControl"
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="100" d:DesignWidth="200"
DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">

<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
    <TextBlock Text="{Binding Property}"/>
</Grid>
</UserControl>

代码背后:

public partial class CustomUserControl : UserControl, INotifyPropertyChanged
{
    public static readonly DependencyProperty DPTestProperty = DependencyProperty.Register("DPTest", typeof(bool), typeof(CustomUserControl), new PropertyMetadata(default(bool), propertyChangedCallback));
    public bool DPTest
    {
        get
        {
            return (bool)GetValue(DPTestProperty);
        }
        set
        {
            SetValue(DPTestProperty, value);
        }
    }
    private bool _property;
    public bool Property
    {
        get
        {
            return _property;
        }
        set
        {
            _property = value;
            RaisePropertyChanged("Property");
        }
    }
    private static void propertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = d as CustomUserControl;
        control.Property = (bool)e.NewValue;
    }

    public CustomUserControl()
    {
        InitializeComponent();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

在我把这个用户控制数据上下文设置为我的视图模型的窗口中:

<phone:PhoneApplicationPage
x:Class="DPTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:my="clr-namespace:DPTest"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Main, Source={StaticResource Locator}}">

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
        <TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <my:CustomUserControl Name="cstom" DPTest="{Binding Property}"/>
    </Grid>

</Grid>

</phone:PhoneApplicationPage>

在视图模型中,我具有绑定到DPTest的属性。

public class MainViewModel : ViewModelBase
{
    private bool _property;

    public bool Property
    {
        get { return _property; }
        set
        {
            _property = value;
            RaisePropertyChanged("Property");
        }
    }

    public MainViewModel()
    {
        Property = true;
    }
}

当我运行此应用程序时,Textblock的值为False,但这应该为True,甚至不调用propertyChangedCallback。我需要做什么?

由于

2 个答案:

答案 0 :(得分:2)

试试这个:

<UserControl x:Class="DPTest.CustomUserControl"
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="100"
d:DesignWidth="200"
x:Name="self">

<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
    <TextBlock Text="{Binding Property, ElementName=self}"/>
</Grid>

答案 1 :(得分:1)

你有将UserControl DataContext绑定到自身,因为你想将CustomUserControl中存在的Property绑定到其中的TextBlock,这完全没问题。

但是当你在CustomUserControl中使用Window时,它将不会继承Window的DataContext,因为它显式设置了UserControl声明。因此,绑定引擎试图在UserControl中查找属性,但它无法正常使用。

注意:绑定引擎在其DataContext中查找属性,否则指示使用RelativeSource,ElementName,x:Reference等查找其他位置。

所以你需要手动为绑定引擎提供如下的属性实例:

<my:CustomUserControl Name="cstom"
                      DPTest="{Binding Path=DataContext.Property, 
                                       ElementName=LayoutRoot}"/>

使用DPTest="True" 的说明:

由于您已经手动将值提供给DP,因此绑定引擎不必担心在DataContext中找到它。