gpt4 book ai didi

c# - ViewModel 属性在其对应的 CustomControl 属性更新时未更新

转载 作者:行者123 更新时间:2023-12-03 10:36:30 25 4
gpt4 key购买 nike

我正在尝试将 VideoPreview 自定义控件类中的 IntPtr VidHandle 属性绑定(bind)到其 View 模型 (vm:DebugHiResCameraWindowViewModel) 中的 IntPtr PreviewHandle。

在 VideoPreview 的构造函数中,我调用:

this.VidHandle = picBox.Handle;

更新 VideoPreview 的 VidHandleProperty DependencyProperty。这完美地工作。但是,ViewModel 中的 PreviewHandle 属性并未更新。当我打电话时:
camera.StartVideoStream(PreviewHandle);

在 View 模型中,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>

视频预览类:
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);
}
});
}
}
}

最佳答案

看起来像 VidHandleVideoPreview控件绑定(bind)到 PreviewHandle您的VideoPreview控制(不存在)。

开始调试时检查输出窗口,它应该会显示绑定(bind)错误(例如,当它找不到属性时)。

也许这就是你所追求的?

<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 的默认值(可以在元数据中设置) ,但它不能属于 PictureBox,因为 DP 是静态的)。不确定这是否合适,但它有效:

在您的 VideoPreview构造函数,添加:
base.Loaded += VideoPreview_Loaded;

并添加
void VideoPreview_Loaded(object sender, RoutedEventArgs e)
{
this.VidHandle = picBox.Handle;
}

在 View 中,更新绑定(bind):
VidHandle="{Binding PreviewHandle, UpdateSourceTrigger=PropertyChanged}"

您可能还想要 Mode=OneWayToSource , 假设句柄应该只来自 VideoPreview

关于c# - ViewModel 属性在其对应的 CustomControl 属性更新时未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26024197/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com