我想我有点卡在WPF DataBinding的机制上。到目前为止,我已经把它想象成这样:DataBinding的任何目标必须是DependencyProperty.Keeping,记住,我设计了一个非常简单的基于按钮的UserControl,如下所示(归结为最必要的部分):
XAML
<Button x:Class="MyNamespace.IconButton"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image x:Name="imIcon"
Source="{Binding Path=ImageSource}"
Grid.Column="0"
Width="16" Height="16"
Margin="0,0,5,0"/>
<TextBlock x:Name="tbText" Text="{Binding Path=Text}" Grid.Column="1"/>
</Grid>
</Button>
C#
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace MyNamespace
{
public partial class IconButton : Button
{
public string Text
{
get { return this.tbText.Text; }
set { this.tbText.Text = value; }
}
public ImageSource ImageSource
{
get
{
return (ImageSource)GetValue(ImageSourceProperty);
}
set
{
SetValue(ImageSourceProperty, value);
}
}
public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.Register("ImageSource",typeof(ImageSource), typeof(IconButton));
public IconButton()
{
InitializeComponent();
}
}
}
使用此控件非常简单:
<v:IconButton Margin="5,0,0,0" Height="24" Width="100"
Text="reload"
ImageSource="..\Resources\images\refresh.png"/>
Visual Studio Designer显示按钮和文本,但拒绝评估依赖项属性“ImageSourceProperty”。当我将'Text'实现为DependencyProperty时也会发生同样的情况。为什么这样做?
而且,为什么我需要一个常规的'ImageSource'呢?如果我从我的代码中删除此属性,VS XAML编辑器(使用控件)将使用“System.Windows.DependencyProperty MyNamespace.IconButton.ImageSourceProperty”(而不是常规属性描述)Tooltip ImageSource属性,这意味着它可以正确解析依赖属性,然而我不能以这种方式设置任何值(“附加属性没有设置器”)。为什么我只能通过xaml的常规属性设置dependecy属性的值?
最后,我有另一个问题。为了简化说明,我在此示例中使用了Article-Category设置。 UI应该允许用户重新分类商店文章。
<ListView x:Name="lvArticles"
ItemsSource="{Binding Path=Articles}"
IsSynchronizedWithCurrentItem="True"/>
<ComboBox IsSynchronizedWithCurrentItem="True"
x:Name="cbCategories"
ItemsSource="{Binding Path=Categories}"
SelectedItem="{Binding Path=Articles.CurrentItem.Category, Mode=TwoWay}"/>
我可以通过在cbCategories中进行选择来改变我的文章(即设置新类别),但是当从lvArticles中选择文章时,cbCategories不会自动设置为相关的类别。我正在做什么或者这是另一个WPF异常现象有什么问题吗?
提前感谢任何提示...
修改
从昨天开始,除了这种奇怪的ComboBox行为之外,我还没有考虑过任何事情。我在代码中发现的第一个缺陷是ViewModel中进入ComboBox的Equals
方法缺少覆盖。结果,没有任何机会成为SelectedItem - 所有ItemSource的元素与SelectedItem的比较都导致了一个整洁的'False'。我现在修补了这个。但在我的Master-Detail-View中,更改所选主记录时,详细信息仍然不会捕捉到正确的值。
另一个编辑
为了弥补这一点,我创造了一个非常丑陋的事件驱动的解决方法。
<ListView x:Name="lvArticles"
ItemsSource="{Binding Path=Articles}"
IsSynchronizedWithCurrentItem="True"
SelectionChanged="LvArticlesSelectionChanged"/>
底层事件处理程序如下所示:
private void LvArticlesSelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
ArticleViewModel avm = this.Articles.SelectedItem as ArticleViewModel;
foreach (CategoryViewModel cvm in this.ViewModel.Categories)
{
if( cvm.Equals( avm.Category ) )
{
this.cbCategories.SelectedItem = cvm;
}
}
}
这是我能想象到的最难看的解决方案 - 我们有什么绑定?但是,由于我必须提供,我会继续这样做,直到有人得到一个很好的解释......
答案 0 :(得分:0)
您将DataSource绑定到Button,而不是绑定到IconButton:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
我的猜测是你希望绑定到原来的父母身上?
两个选项:
最简单的解决方案:
更改DataSource事物以找到正确的父级。
DataContext="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type MyNamespace:IconButton}}}"
重写您的控件,以便它使用ControlTemplate
,因此您可以对要从父控件接管的属性使用TemplateBindings
:
<Button x:Class="MyNamespace.IconButton">
<Button.Template>
<ControlTemplate TargetType="MyNamespace:IconButton">
<Grid>
...
<Image x:Name="imIcon"
Source="{TemplateBinding ImageSource}"
Grid.Column="0"
Width="16" Height="16"
Margin="0,0,5,0"/>
<TextBlock x:Name="tbText" Text="{TemplateBinding Text}" Grid.Column="1"/>
</Grid>
</ControlTemplate>
<Button.Template>
</Button>