这是我关于stackoverflow的第一个问题。 我有一个Usercontrol包含一个viewModel作为静态资源。比我有一个包含这个UserModel的窗口。我想将命令从Window发送到usercontrol使用的viewmodel。所以我将Viewmodel类绑定到Usercontrol,并将Window作为静态资源绑定到Window。但是viewmodell是2次实例化的。一旦从Window和一次从usercontrol。我究竟做错了什么?
这是usercontrol的xaml:
<UserControl x:Class="ScanVM.ScanView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:t="clr-namespace:ScanVM"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="501.305">
<UserControl.Resources>
<t:ScanVM x:Key="ABC"/>
</UserControl.Resources>
<DockPanel DataContext="{Binding Source={StaticResource ABC}}">
<Grid ShowGridLines="True" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="10*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Label Content="Geräte:" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Right" Margin="0,10,10,0"/>
<DataGrid ItemsSource="{Binding Path=ScanIDs, Mode=OneWay}" Grid.Column="1" HorizontalAlignment="Left" Margin="10,10,0,0" Grid.Row="1" VerticalAlignment="Top" AutoGenerateColumns="false" Height="152" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ScanIds}" ClipboardContentBinding="{x:Null}" Header="Bezeichnung" MinWidth="200"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</DockPanel>
这是我窗口的代码:
<Window x:Class="ScanViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ribbon="clr-namespace:System.Windows.Controls.Ribbon;assembly=System.Windows.Controls.Ribbon"
xmlns:self="clr-namespace:ScanViewer"
xmlns:t="clr-namespace:ScanVM;assembly=ScanVM"
mc:Ignorable="d"
Title="Scan-Viewer" Height="682.225" Width="694">
<Window.Resources>
<t:ScanVM x:Key="ABC"/>
</Window.Resources>
<Window.CommandBindings>
<CommandBinding
Command="self:MainWindow.ExitCommand"
CanExecute="ExitCommand_CanExecute"
Executed="ExitCommand_Execute"/>
</Window.CommandBindings>
<DockPanel>
<ribbon:Ribbon DockPanel.Dock="Top">
<Ribbon.ApplicationMenu>
<RibbonApplicationMenu Visibility="Collapsed">
<RibbonApplicationMenuItem Header="Beenden"/>
<RibbonApplicationMenu.FooterPaneContent>
<RibbonButton Label="Exit"/>
</RibbonApplicationMenu.FooterPaneContent>
</RibbonApplicationMenu>
</Ribbon.ApplicationMenu>
<RibbonTab Header="Start">
<RibbonGroup Header="Programm">
<RibbonButton Label="Beenden" Margin="0,5,0,0" Command="self:MainWindow.ExitCommand" />
</RibbonGroup>
<RibbonGroup Header="Scannen">
<RibbonButton Label="Daten Scannen" Margin="0,5,0,0" Command="{Binding ScanCmd, Source={StaticResource ABC}}"/>
</RibbonGroup>
</RibbonTab>
</ribbon:Ribbon>
<Grid DockPanel.Dock="Top" Height="464">
<t:ScanView DataContext="{Binding Source={StaticResource ABC}}"/>
</Grid>
</DockPanel>
这是我的Viewmodel的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Windows.Input;
using System.Threading;
using MVVMBase;
namespace ScanVM
{
public class ScanVM : ViewModelBase
{
private ICommand _doWorkCmd;
private ICommand _scanCmd;
private bool scanAllowed = false;
public List<int> ScanIDs
{
get;
set;
}
public ScanVM()
{
_doWorkCmd = new DelegateCommand((param) => DoWork());
_scanCmd = new DelegateCommand((param) => Scan());
}
public bool NWScanAllowed(object executeAllowed)
{
return scanAllowed;
}
public ICommand WorkCmd
{
get { return _doWorkCmd; }
}
public ICommand ScanCmd
{
get
{
return _scanCmd;
}
}
private void Scan()
{
scanAllowed = true;
}
private void DoWork()
{
}
}
}
答案 0 :(得分:0)
答案取决于您要对共享对象执行的操作。
您可以将ABC移至<Application.Resources>
标记内的App.xaml,以便在整个项目中共享它。
或者您可以删除用户控件中的那个并在窗口的资源中使用ABC。
在这种情况下,您需要一个有效的参考路径来处理来自用户控件的 窗口资源中的ABC 。
将我们带到这两种情况:
因此,如果您的用户控件是所提到窗口的一部分(并且,如果窗口的DataContext设置为ABC),那么请在用户控件内部进行说明像这样引用它:
<DockPanel DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext}">