C# 为什么自定义控件上的绑定不起作用?
我有一个主视图,我正在使用我创建的名为VideoPlayer的组件。VideoPlayer是一个网格,它有一个MediaElement、一些按钮和一个滑块来控制视频播放。 我试图通过将VideoPlayer中的属性绑定到MainView中的属性来设置要在MainView中播放的视频的路径。 守则的有关部分如下: VideoPlayer.xaml中的代码片段:C# 为什么自定义控件上的绑定不起作用?,c#,wpf,mvvm,data-binding,C#,Wpf,Mvvm,Data Binding,我有一个主视图,我正在使用我创建的名为VideoPlayer的组件。VideoPlayer是一个网格,它有一个MediaElement、一些按钮和一个滑块来控制视频播放。 我试图通过将VideoPlayer中的属性绑定到MainView中的属性来设置要在MainView中播放的视频的路径。 守则的有关部分如下: VideoPlayer.xaml中的代码片段: <MediaElement Name="MediaElement" Grid.Row="0" Load
<MediaElement
Name="MediaElement"
Grid.Row="0"
LoadedBehavior="Manual"
Stretch="Uniform"
Source="{Binding VideoLocation}" />
VideoPlayer在MainView.xaml中使用,MainView.xaml是以下MVVM:
<ReuseableComponents:VideoPlayer VideoLocation="{Binding VideoPath}"/>
如果我删除VideoLocation绑定并在MainView.xaml中硬编码路径,视频将正常播放:
<ReuseableComponents:VideoPlayer VideoLocation="C:\Movies\FightClub.mp4"/>
在此之前,UserControl没有设置name属性,网格没有设置DataContext属性。绑定是相对于控件的DataContext进行的,您可能没有设置DataContext。您需要将其相对于控件进行设置。为控件指定如下名称:
<UserControl x:Class="YourApp.YourUserControl"
... etc ...
x:Name="_this">
<UserControl x:Name="TheControl" ...>
<Grid DataContext={Binding ElementName=TheControl} ...>
...
</Grid>
</UserControl>
或者,您也可以使用相对资源绑定,将AncestorType设置为您的用户控件类型。问题可能是您在顶层将VideoPlayer用户控件的DataContext设置为自身。这意味着您重写控件应继承的MainView DataContext,即此绑定:
<ReuseableComponents:VideoPlayer VideoLocation="{Binding VideoPath}"/>
尝试绑定到VideoPlayer控件而不是MainView DataContext
您可以在包含的元素上设置VideoPlayer的内部DataContext,如下所示:
<UserControl x:Class="YourApp.YourUserControl"
... etc ...
x:Name="_this">
<UserControl x:Name="TheControl" ...>
<Grid DataContext={Binding ElementName=TheControl} ...>
...
</Grid>
</UserControl>
那没用。我在VideoPlayer.xaml和MainView.xaml中都试过了,我不确定你认为应该使用哪一个。另外,我调用DataContext=this;在VideoPlayer的构造函数中。Idk,如果这算是设置DataContext的话。那应该可以,对我来说当然可以。我注意到你正在将LoadedBehavior设置为Manual,实际上你正在调用MediaElement.Play,是吗?是的,我这样做是为了视频不会自动播放。我有一个按钮可以调用。Play和另一个按钮可以调用。暂停我能建议的另一件事是将您的属性更改为Uri类型而不是字符串。您绑定的MediaElement属性实际上是Uri类型;字符串工程可以在我使用的网络版本中找到,但可能您使用的版本更旧?如果这不起作用,那么在这里贴一个帖子,我会再帮你看一看。就这样了。我删除了'DataContext=this;`并使用了第二个片段。现在一切都好了。谢谢你和马克·费尔德曼!
Source="{Binding ElementName=_this, Path=VideoLocation}"
<ReuseableComponents:VideoPlayer VideoLocation="{Binding VideoPath}"/>
<UserControl x:Name="TheControl" ...>
<Grid DataContext={Binding ElementName=TheControl} ...>
...
</Grid>
</UserControl>