【问题标题】:User control's dependency property not binding用户控件的依赖属性未绑定
【发布时间】:2014-02-01 20:03:35
【问题描述】:

我有依赖属性的用户控制。当我尝试在 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 甚至没有被调用。我需要做什么?

谢谢

【问题讨论】:

  • {Binding Main, Source={StaticResource Locator}} 中的 MainLocator 是什么?
  • 它是使用 MvvmLight 添加的 ViewModelLocator 的实例。它适用于普通的 TextBlock(当我运行它时它的值为 True)。
  • 所以Locator.Main 属于MainViewModel 类型并且具有Property 属性。如果在同一页面上添加&lt;Checkbox IsChecked={Binding Property}/&gt;,它会被检查吗?
  • 是的,和你写的完全一样。
  • 而且,正如您所提到的,如果您使用 DPTest="True" 而不是绑定,则 TextBlock 显示为 true。对吗?

标签: c# wpf windows-phone-8


【解决方案1】:

试试这个:

<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>

【讨论】:

  • 感谢您的回复,但它不起作用。我认为用户控制没有问题,因为当我将 DPTest="{Binding Property}" 更改为 DPTest="True" 时,它就可以工作了。
  • 你真的尝试过我的修改吗? @dkozl 在详细信息中进行了解释。您的测试 (DPTest="True") 并不能证明问题出在控制之外。对我来说,您的测试确实证明在控件中设置 DataContext 是问题所在。因为对于您的测试,根本不需要(使用)DataContext。控件使用 DataContext 来解析绑定(不起作用)。
【解决方案2】:

您已经将 UserControl DataContext 绑定到自身,因为您想将 CustomUserControl 中的 Property 绑定到其中的 TextBlock,这完全没问题。

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

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

所以你需要像这样手动提供绑定引擎属性实例:

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

使用DPTest="True"的说明

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多