我现在遇到一些在Windows Phone应用程序中绑定某些自定义控件的问题。通常这不是问题,但显然我的思想今天无法理解。
所以我正在进行MVVM样式设置,这很好。我的页面有视图,也有视图模型。现在在WebClient回调中,我将视图的dataContext分配给我的ViewModel中的模型列表,到目前为止很简单...现在在我看来,我在datatemplate中创建了一个带有自定义控件的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 / Setters中运行逻辑。但是,如果我尝试从绑定源设置这些自定义对象,它实际上不会设置。
这是有效的:
<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中设置依赖于模型知识的绑定。谢谢!
答案 0 :(得分:1)
您的DependencyProperty形成错误。 (我也没有看到你的班级或XAML中定义的Champ_Grid,但我认为这是一个省略)
在代码中设置ChampVisibility = true,因为它与DependencyProperty无关。
您可以轻松辨别,因为您的DP的默认值无效。它将编译,但实例构造函数将通过异常,如果它被调用。
new 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上的Binding有效,因为它绑定到DataContext(您的模型),因此它可能显示正确的值。 不会设置UserControl中的Dependency属性。
在Visual Studio中使用propdp代码片段,这样您就不必担心依赖属性声明的复杂性。
还有check this out了解有关依赖属性的更多信息