我有2个按钮的视图(片段)。如果单击左按钮,则将打开“视图2”。如果单击右键,则将打开“视图3”。我正在使用Caliburn Micro。因此,Button的x:Name值是单击按钮后调用的View Model方法的名称。
View1:
<StackPanel Name="PnlButtons"
Grid.Row="1"
Grid.ColumnSpan="2"
HorizontalAlignment="Center"
Orientation="Horizontal"
Opacity="1">
<Button x:Name="ArtikelAuswahl"
Background="Bisque"
Content="Artikel auswählen"
Width="170" Height="25"
FontFamily="Verdana">
</Button>
<Button x:Name="SonderAuswahl"
Background="BlanchedAlmond"
Content="Sonderartikel hinzufügen"
Width="170" Height="25"
FontFamily="Verdana">
</Button>
</StackPanel>
这里是单击按钮后调用的2种方法。您可以看到它们具有相同的名称。现在人们说禁止在视图模型中打开视图。这就是为什么要打开新视图时在方法中使用IWindowManager实例winmanager的原因。我没有创建一个新的视图实例,而是创建了一个新的viewmodel实例! 第一个问题:这是否违反MVVM的规则?
ViewModel1:
public class CreateLieferscheinViewModel : Conductor<object>
{
private IWindowManager winmanager = new WindowManager();
public InventurartikelViewModel inventur = new InventurartikelViewModel();
public SonderartikelViewModel sonder = new SonderartikelViewModel();
public void ArtikelAuswahl()
{
wwinmanager.ShowWindow(inventur, null, null);
}
public void SonderAuswahl()
{
winmanager.ShowWindow(sonder,null,null);
}
public void ArtikellisteUmformen()
{
for (int k = 0; k < inventur.Artikelliste.Count; k++)
{
Artikelsammlung.Add(new ArtikelModel()); //every selected article will get added to Artikelsammlung
//get each selected article unfiltered (unformatted)
Artikelsammlung[k].Bezeichnung = inventur.Artikelliste[k].ToString();
//Extract the unit out of the Artikel-String
Artikelsammlung[k].Einheit = Zeichenketten.TextFindenVonBisEnde(Artikelsammlung[k].Bezeichnung, "<", ">");
//remove "in <Einheit>" from the Artikel-String
Artikelsammlung[k].Bezeichnung = Zeichenketten.EinheitEntfernen(Artikelsammlung[k].Bezeichnung);
/*
* Bezeichnung and Einheit are now properly formatted...
*/
}
}
}
private ObservableCollection<ArtikelModel> _artikelsammlung;
public ObservableCollection<ArtikelModel> Artikelsammlung
{
get { return _artikelsammlung; }
set
{
_artikelsammlung = value;
OnPropertyChanged("Artikelsammlung");
}
}
确定,现在说ArtikelAuswahl被调用。感谢Caliburn Micro,View2显示:
View2:
<Window x:Class="Lieferscheine.Views.InventurartikelView"
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:local="clr-namespace:Lieferscheine.Views"
xmlns:main="clr-namespace:Lieferscheine"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d" Title="Inventurartikel suchen"
Height="450" Width="370">
<StackPanel Height="423" VerticalAlignment="Bottom">
<Label Name="lblArtikelbezeichnung" Content="Artikelbezeichnung:" Margin="20, 20, 20, 0"></Label>
<TextBox Name="BezText"
Width="Auto"
Margin="20, 0, 20, 0"
IsEnabled="{Binding Path=BezEnabled}"
cal:Message.Attach="[Event KeyUp] = [Action KeyUpBez($executionContext)]">
</TextBox>
<Label Name="lblLieferant" Content="Lieferant:" Margin="20, 0, 20, 0"></Label>
<TextBox Name="LiefText"
Width="Auto"
Margin="20, 0, 20, 0"
IsEnabled="{Binding Path=LiefEnabled}"
cal:Message.Attach="[Event KeyUp] = [Action KeyUpLief($executionContext)]">
</TextBox>
<Button Name="SucheArtikel"
Content="Suchen"
Width="100" Height="25"
Margin="20, 10,240, 10">
</Button>
<Button x:Name="GesamteListeAnzeigen"
Content="Gesamte Liste anzeigen"
Width="150" Height="26"
Margin="0, -50, 20, 0"
HorizontalAlignment="Right"/>
<main:MultipleSelectionListBox
x:Name="LboxAddArtikel"
SelectionMode="Multiple"
Width="320" Height="220"
Margin="20, 10, 20, 10"
BindableSelectedItems="{Binding Path=MyCollectionOfSelectedIDs}">
</main:MultipleSelectionListBox>
<Button x:Name="FuegeArtikelHinzu"
Content="Hinzufügen"
Width="100" Height="25">
</Button>
</StackPanel>
View2是绑定到ViewModel2的数据。但是在向您展示ViewModel2之前,我想向您展示在View2中可以做什么:
我从列表框中选择3篇文章,然后单击view2
底部的按钮将这些文章添加到列表中:
<Button x:Name="FuegeArtikelHinzu" Content="Hinzufügen" Width="100" Height="25"> </Button>
将文章添加到FuegeArtikelHinzu
中方法viewmodel2
中的列表中:
ViewModel2:
public class InventurartikelViewModel : Screen
{
private List<string> _artikelliste = new List<string>();
public List<string> Artikelliste
{
get { return _artikelliste; }
set
{
_artikelliste = value;
OnPropertyChanged("Artikelliste");
}
}
public void FuegeArtikelHinzu()
{
try
{
//This adds only the multiple selected items to a list
var multi = MyCollectionOfSelectedIDs;
int i = 0;
foreach (string item in multi)
{
Artikelliste.Insert(i, item);
i++;
}
MessageBox.Show("Artikel hinzugefügt!"); //ok, all added...
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Zuerst Artikel auswählen!"); //you must select an article first...
}
}
}
这是我的问题!我需要列表artikelliste
中的选定文章在我的视图模型1中!!但是我陷入了死胡同。我听说通过实现IMessenger服务可以解决此问题,但是在我的示例中我不明白它是如何工作的。根据我的示例,我需要怎么做才能将artikelliste
传递给ViewModel1
?如果您不熟悉Caliburn Micro,请从头开始或通过框架发布另一个解决方案,我不在乎。预先感谢您的帮助!
编辑:
我现在可以在ViewModel1中访问ViewModel2及其Artikelliste
属性。但是,我想在ViewModel2的ArtikellisteUmformen()
更新后立即调用ViewModel1的方法Artikelliste
。我怎么做?这就是我想做的:
Artikelliste
填充后,您可以在ViewModel2上调用一个事件,例如ArtikelListeUpdated。 ViewModel1侦听该事件,并在必要时对其做出反应。您甚至不需要该事件,以防您不必立即对此做出反应。
创建ViewModel实例并使用WindowManager接口并不针对MVVM。您应该可以做到这一点。
我对Caliburn Micro Framework不熟悉。但是呢: