![](/img/trans.png)
[英]WPF Combobox in view not updating when bound property in viewmodel updated
[英]ViewModel property not updating when it's corresponding CustomControl property is updated
我试图将VideoPreview定制控件类中的IntPtr VidHandle属性绑定到其视图模型(vm:DebugHiResCameraWindowViewModel)中的IntPtr PreviewHandle。
在VideoPreview的构造函数中,我调用:
this.VidHandle = picBox.Handle;
更新VideoPreview的VidHandleProperty DependencyProperty。 这很完美。 但是,未更新ViewModel中的PreviewHandle属性。 到我打电话时:
camera.StartVideoStream(PreviewHandle);
在视图模型中,PreviewHandle为0,因为它从未从VideoPreview更新。 我感觉我的DependencyProperty VidHandleProperty没有正确实现,但是我可能错了。
以下是一些代码段:
主窗口XAML:
<Window
x:Class="AoiImageLift.Views.DebugHiResCameraWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:AoiImageLift.Presentation.ViewModels"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:com="clr-namespace:AoiImageLift.Components"
xmlns:local="clr-namespace:AoiImageLift"
Title="DebugHiResCameraWindow"
Name="hiResWindow"
Height="300"
Width="300">
<Window.Resources>
<vm:DebugHiResCameraWindowViewModel x:Key="viewModel"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<com:VideoPreview
DataContext="{StaticResource viewModel}"
x:Name="videoHost"
VidHandle="{Binding PreviewHandle, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type com:VideoPreview}}}"/>
<Button
DataContext="{StaticResource viewModel}"
Grid.Row="1"
Width="100"
Height="40"
Command="{Binding StartCaptureCommand}"
Content="Start"/>
</Grid>
VideoPreview类:
public class VideoPreview : WindowsFormsHost
{
private PictureBox picBox;
public static readonly DependencyProperty VidHandleProperty =
DependencyProperty.Register(
"VidHandle",
typeof(IntPtr),
typeof(VideoPreview),
new FrameworkPropertyMetadata
{
BindsTwoWayByDefault = true
});
public VideoPreview() : base()
{
picBox = new PictureBox();
picBox.Width = (int) this.Width;
picBox.Height = (int) this.Height;
this.VidHandle = picBox.Handle;
this.Child = picBox;
}
public IntPtr VidHandle
{
get
{
return (IntPtr) GetValue(VideoPreview.VidHandleProperty);
}
set
{
SetValue(VideoPreview.VidHandleProperty, value);
}
}
}
查看模型类:
public class DebugHiResCameraWindowViewModel : ViewModel
{
private Uri capturedImage;
private BitmapImage bmp;
private ISnapImages camera;
public DebugHiResCameraWindowViewModel()
{
camera = LumeneraCamera.Instance;
bmp = new BitmapImage();
}
public IntPtr PreviewHandle { get; set; }
public Uri CapturedImage
{
get { return capturedImage; }
set { capturedImage = value; OnPropertyChanged("CapturedImage"); }
}
public ICommand StartCaptureCommand
{
get
{
return new DelegateCommand(() =>
{
try
{
camera.StartVideoStream(PreviewHandle);
}
catch (CustomException ex)
{
MessageBox.Show(ex.Message, ex.Caption, ex.Button, ex.Image);
}
});
}
}
}
它看起来像VidHandle
的的VideoPreview
控件绑定到PreviewHandle
您的VideoPreview
控制(不存在)。
开始调试时,请检查输出窗口,该窗口应显示绑定错误(例如,找不到属性时)。
也许这就是你所追求的?
<Window
x:Class="AoiImageLift.Views.DebugHiResCameraWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:AoiImageLift.Presentation.ViewModels"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:com="clr-namespace:AoiImageLift.Components"
xmlns:local="clr-namespace:AoiImageLift"
Title="DebugHiResCameraWindow"
Name="hiResWindow"
Height="300"
Width="300">
<!-- CHANGED HERE: set DataContext of Window -->
<Window.DataContext>
<vm:DebugHiResCameraWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- CHANGED HERE: removed DataContext (set at Window) -- updated binding -->
<com:VideoPreview
x:Name="videoHost"
VidHandle="{Binding PreviewHandle}"/>
<!-- CHANGED HERE: removed DataContext (set at Window) -- binding OK -->
<Button
Grid.Row="1"
Width="100"
Height="40"
Command="{Binding StartCaptureCommand}"
Content="Start"/>
</Grid>
DataContext是继承的,您可以在Window上设置它,子控件将知道它。
回复:注释... VM通常会优先处理-如果在所有getter / setter上设置断点,则可以看到顺序... 0来自DP的默认值(可以在meta中设置) ,但不能属于PictureBox
因为DP是静态的)。 不知道这是否合适,但是它可以工作:
在您的VideoPreview
构造函数中,添加:
base.Loaded += VideoPreview_Loaded;
并添加
void VideoPreview_Loaded(object sender, RoutedEventArgs e)
{
this.VidHandle = picBox.Handle;
}
在视图中,更新绑定:
VidHandle="{Binding PreviewHandle, UpdateSourceTrigger=PropertyChanged}"
您可能还需要Mode=OneWayToSource
,假定句柄应仅来自VideoPreview
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.