【问题标题】:Bind user control dependency properties in MVVM style Windows Phone app在 MVVM 样式的 Windows Phone 应用程序中绑定用户控件依赖项属性
【发布时间】:2013-01-18 18:16:16
【问题描述】:

我现在在 Windows Phone 应用程序中绑定一些自定义控件时遇到了一些问题。通常这从来都不是问题,但显然我今天无法理解这一点。

所以我正在做一个很好的 MVVM 样式设置。我的页面带有视图和视图模型。现在在 WebClient 回调中,我将视图的 dataContext 分配给我的 ViewModel 中的模型列表,到目前为止非常简单......现在在我的视图中,我在数据模板中创建了一个带有自定义控件的 ListBox,它基本上是一个单元格名单。我再次将我的用户控件 dataContext 设置为绑定,并将所有模型值绑定到常规 UI 元素没有问题。

这是一个示例:

<Grid Grid.Column="0">
            <Image Source="{Binding SmallPath}" VerticalAlignment="Top"/>
        </Grid>

        <Grid Grid.Column="1">
            <StackPanel Margin="12,0,0,0">
                <TextBlock x:Name="MemberId_TextBlock" Text="{Binding MemberId}" FontSize="28"
                           Margin="0,-8,0,0"
                           Foreground="{StaticResource PhoneForegroundBrush}"/>
                <StackPanel Orientation="Horizontal" Margin="0,-11,0,0">
                    <TextBlock Text="{Binding DaysReported}" FontSize="42"
                               Margin="0,0,0,0"
                               Foreground="{StaticResource PhoneAccentBrush}"/>
                    <TextBlock Text="days" FontSize="24"
                               Margin="3,19,0,0"
                               Foreground="{StaticResource PhoneSubtleBrush}"/>
                </StackPanel>
            </StackPanel>
        </Grid>

这是在我的用户控件中,这是用户控件所在的视图:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <ListBox Name="TopSpotter_ListBox" ItemsSource="{Binding}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <!--<TextBlock Text="{Binding MemberId}"/>-->
                    <controls:TopSpotterItemControl DataContext="{Binding}"/>
                    <Grid Height="18"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

现在这已经足够好了,但我想在我的视图中设置来自我的模型的数据,如布尔值,确定我是否应该显示某些网格等。所以如果我尝试在我的控件中显式设置依赖属性例如,它会触发并在 Getter/Setter 中运行逻辑。但是,如果我尝试从绑定源设置这些自定义对象,它实际上不会设置。

以下是有效的:

<controls:TopSpotterItemControl ChampVisibility="True">

这种方式会触发 ChampVisibility 属性,然后在用户控件后面的代码中我可以设置可见性。

这是失败的,但我想工作:

<controls:TopSpotterItemControl ChampVisibility="{Binding IsChamp">

此外,我仍然可以将 DataContext 设置为 {Binding} 并且结果将保持不变。

在这种情况下,IsChamp 是我的模型的一部分,我想将它绑定到这个用户控件,我猜它来自于在 viewModel 的视图上设置的 dataContext。我不确定我能做些什么来让绑定工作等,而不必设置自定义属性。

最后,这是我的用户控件:

public partial class TopSpotterItemControl : UserControl
{
    public string MemberId
    {
        get
        {
            return this.MemberId_TextBlock.Text;
        }
        set
        {
            this.MemberId_TextBlock.Text = value;
        }
    }

    public bool ChampVisibility {
        set
        {
            if (value)
            {
                this.Champ_Grid.Visibility = System.Windows.Visibility.Visible;
            }
        }
    }

    public static readonly DependencyProperty MemberNameProperty =
        DependencyProperty.Register("MemberId", typeof(string), typeof(TopSpotterItemControl), new PropertyMetadata(null));

    public static readonly DependencyProperty ChampVisibilityProperty =
        DependencyProperty.Register("ChampVisibility", typeof(bool), typeof(TopSpotterItemControl), new PropertyMetadata(null));

    public TopSpotterItemControl()
    {
        InitializeComponent();
    }
}

有点啰嗦,我希望我能清楚地说明这个问题。到目前为止,我的一个主要问题是,我想通过在 xaml 中显式设置的依赖属性将尽可能多的控制抽象到用户控件,而不是在其 xaml 中设置依赖于模型知识的绑定。谢谢!

【问题讨论】:

  • 你是不是缺少一个用于 ChampVisibility 的 Getter?尝试添加它,看看是否能解决您的问题。
  • 嘿,贾斯汀,我不认为这是问题所在,但无论如何我都尝试过,但无济于事。它似乎仍然与何时涉及绑定而不是在明确设置时有关。

标签: silverlight windows-phone-7 wpf-controls windows-phone-8 windows-phone


【解决方案1】:

您的 DependencyProperty 格式错误。 (我也没有在您的课程或 XAML 中看到 Champ_Grid 定义,但我认为这是一个遗漏)

在代码中设置 ChampVisibility = true 有效,因为它与 DependencyProperty 无关。

您可以轻松判断,因为您的 DP 的默认值无效。它会编译,但如果实例构造函数被调用,它将通过异常。

新的 PropertyMetadata(null)

bool = null = 异常

如果您从某个地方调用 GetValue(TopSpotterItemControl.ChampVisibilityProperty),您可以确认以上所有内容。

您应该对属性更改处理程序中的实例字段进行更改,并如下声明该属性,它将起作用: 请注意,属性必须更改(不仅仅是设置)才能引发事件。

public bool ChampVisibility
{
    get { return (bool)GetValue(ChampVisibilityProperty); }
    set { SetValue(ChampVisibilityProperty, value); }
}

public static readonly DependencyProperty ChampVisibilityProperty =
    DependencyProperty.Register("ChampVisibility ", typeof(bool), typeof(TopSpotterItemControl), new PropertyMetadata(true, (s, e) =>
{
    TopSpotterItemControl instance = s as TopSpotterItemControl;
    instance.Champ_Grid.Visibility = instance.ChampVisibility ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
}));

顺便说一句,你的 MemberId DependencyProperty 也是完全错误的,无法工作。

注意: TextBox 上的绑定有效,因为它绑定到 DataContext(您的模型),因此它可能显示正确的值。 但是永远不会设置 UserControl 中的 Dependency 属性。

在 Visual Studio 中使用 propdp 代码-sn-p,这样您就不必担心依赖属性声明的复杂性。

也可以check this out 了解有关依赖属性的更多信息

【讨论】:

    猜你喜欢
    • 2013-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多