我完全失去了依赖对象和绑定。我常常在不了解原因和方法的情况下开展工作,这个问题就是要知道应该发生什么。
我有一个微小的用户控件,带有以下XAML
<Grid>
<Image Source="{Binding Icon}"></Image>
<TextBlock Text="{Binding Title}"></TextBlock>
</Grid>
我的代码背后有
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(Image), typeof(MenuItem));
public Image Icon
{
get { return (Image)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(String), typeof(MenuItem));
public string Title
{
get { return (string)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
除了对此控件和ResourceDictionary的引用之外,我的MainWindow是空的。在后面的MainWindow代码中,我在构造函数中设置了DataContext。
<Window x:Class="AppUi.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:AppUi.Control"
Title="">
//set up to Resource Dictionary - all binding and styling works fine :)
<loc:MenuItem Icon="{Binding MailIcon}" Title="{Binding MailTitle}"></loc:MenuItem>
在MainWindow的ModelView中,我有以下2个属性
private Image_mailIcon;
public Image MailIcon{
//inotifyproperty implementation
}
private string _mailTitle;
public string MailTitle{
//inotifyproperty implementation
}
我的问题是,在UserControl中,我该如何进行绑定?由于它是MainWindow中的用户控件,并且MainWindow已经有一个datacontext,我认为UserControl将从父级继承DataContext(从我读过的内容)。
那么,在我的UserControl XAML中,我应该绑定到MainWindow的Code Behind属性还是ViewModel属性?
换句话说,我的UserControl应该是
<Grid>
<Image Source="{Binding MailIcon}"></Image>
<TextBlock Text="{Binding MailTitle}"></TextBlock>
</Grid>
OR
<Grid>
<Image Source="{Binding Icon}"></Image>
<TextBlock Text="{Binding Title}"></TextBlock>
</Grid>
或者,因为我使用的是DataContext并且UserControl继承了,我甚至还需要Dependancy Properties吗?
答案 0 :(得分:1)
您通常不想覆盖通过可视树传递的DataContext
,因此您可以使用ElementName
内的RelativeSource
或UserControl
绑定来更改绑定上下文。实现此目标的最简单方法是为UserControl
提供一些名称并使用ElementName
绑定
<UserControl ... x:Name="myUserControl">
<!-- ... -->
<Grid>
<Image Source="{Binding Icon, ElementName=myUserControl}"/>
<TextBlock Text="{Binding Title, ElementName=myUserControl}"/>
</Grid>
<!-- ... -->
</UserControl>
这种绑定方式DataContext
是独立的。您也可以创建UserControl
,并假设它始终只使用特定类型的DataContext
,然后您只使用该视图模型类型中的Path
,然后DataContext
{ {1}}必须始终属于其设计的视图模型(主要通过可视树继承)
UserControl
我还会将<UserControl ...>
<!-- ... -->
<Grid>
<Image Source="{Binding MailIcon}"/>
<TextBlock Text="{Binding MailTitle}"/>
</Grid>
<!-- ... -->
</UserControl>
属性的类型从Icon
更改为Image
。您已在ImageSource
内部拥有Image
控制权,而您只想绑定其UserControl
答案 1 :(得分:1)
在UserControl中,我该如何进行绑定? ... UserControl将从父
继承DataContext
这是正确的,UserControl
将从父DataContext
继承Window
。因此,您可以数据从UserControl
直接绑定到父Window.DataContext
。请注意,无论是后面的代码还是单独的视图模型类,您都将绑定到已设置为DataContext
的任何对象。
但是,在这种情况下,您没有 将数据绑定到父{q} DataContext
对象...您还有其他选择。您可以使用RelativeSource Binding
将 数据绑定到您自己的UserControl DependencyProperty
:
<TextBlock Text="{Binding Title, RelativeSource={RelativeSource
AncestorType={x:Type YourPrefix:YourUserControl}}}" />
您也可以为UserControl
命名并引用其属性,如下所示:
<TextBlock Text="{Binding Title, ElementName=YourUserControlName}" />
虽然这个例子似乎更简洁,但不要忽视第一个例子,因为RelativeSource
是一个有用且有实力的朋友。
我应该绑定到MainWindow的Code Behind属性还是ViewModel属性?
这是您的选择......您想要或需要数据绑定到什么?您只需要知道直接数据绑定将使用自动设置DataContext
值,因此如果您不想使用它,那么您只需为{{1}指定不同的数据源如上所示。
最后,关于使用Binding
的需要......如果您正在开发需要提供数据绑定功能的DependencyProperty
,则只需要声明它们。