私はメインViewModelにObservableCollection of ViewModelsを持っています。私はビューを切り替えることができるので、バインディングは正常に動作しているようです。しかし、ObservableCollectionの要素でViewModelBaseのOnPropertyChangedメソッド(他の要素で機能する)を呼び出すと、ViewModelBaseのnull PropertyChanged値が返されます。私のメインのViewModelコンストラクタで子ViewModelプロパティのPropertyChanged値がnullです
:
はここに私のメインのコードスニペットですGBAのROMの読み込みで
public EditorViewModel()
{
base.DisplayName = Strings.EditorName;
_availableEditors = new ObservableCollection<ViewModelBase>();
AvailableEditors.Add(new GBARomViewModel(646, 384));
AvailableEditors.Add(new MonsterViewModel(800, 500));
CurrentEditor = _availableEditors[0];
}
、ViewModelにとモデルプロパティが更新されます。
void RequestOpenRom()
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.DefaultExt = ".gba";
dlg.Filter = "GBA ROM (.gba)|*.gba|All files (*.*)|*.*";
dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
Nullable<bool> result = dlg.ShowDialog();
if (result == true)
{
if(CurrentEditor is GBARomViewModel)
{
(CurrentEditor as GBARomViewModel).ReadRom(dlg.FileName);
}
}
}
で私のメインビュー: TabControlのバリエーション(ビューの切り替えとビューの状態を表示する保護)。 GBARomViewModelで
<controls:TabControlEx ItemsSource="{Binding AvailableEditors}"
SelectedItem="{Binding CurrentEditor}"
Style="{StaticResource BlankTabControlTemplate}"
MinWidth="{Binding CurrentEditorWidth}"
MinHeight="{Binding CurrentEditorHeight}"
MaxWidth="{Binding CurrentEditorWidth}"
MaxHeight="{Binding CurrentEditorHeight}"
Width="{Binding CurrentEditorWidth}"
Height="{Binding CurrentEditorHeight}"
HorizontalAlignment="Left"
VerticalAlignment="Top">
<controls:TabControlEx.Resources>
<DataTemplate DataType="{x:Type vm:GBARomViewModel}">
<vw:GBARomView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:MonsterViewModel}">
<vw:MonsterView />
</DataTemplate>
</controls:TabControlEx.Resources>
</controls:TabControlEx>
(子ViewModelに、AvailableEditorsの要素)
public String CRC32
{
get
{
return _rom.CRC32;
}
set
{
if (value.Equals(_rom.CRC32))
{
return;
}
_rom.CRC32 = value;
OnPropertyChanged("CRC32");
}
}
プロパティは、子ビュー
に結合が今、これはそう、私は後にもそのコードを出してあげるのUserControlです。起動時のその他のプロパティ(LabelWidthやLabelValueなど) XAMLのTextBoxValueに既定値を与えることもできます。
<StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="10, 0, 0, 10" Width="300">
<dlb:DefaultLabelBox LabelWidth="82" TextBoxWidth="100" HorizontalAlignment="Left" LabelValue="{x:Static p:Strings.RomTitle}" TextBoxValue="{Binding Title}" />
<dlb:DefaultLabelBox LabelWidth="82" TextBoxWidth="100" HorizontalAlignment="Left" LabelValue="{x:Static p:Strings.RomGameCode}" TextBoxValue="{Binding GameCode}" />
<dlb:DefaultLabelBox LabelWidth="82" TextBoxWidth="100" HorizontalAlignment="Left" LabelValue="{x:Static p:Strings.RomRomSize}" TextBoxValue="{Binding RomSize}" />
<dlb:DefaultLabelBox LabelWidth="82" TextBoxWidth="100" HorizontalAlignment="Left" LabelValue="{x:Static p:Strings.RomCRC32}" TextBoxValue="{Binding CRC32}" />
<dlb:DefaultLabelBox LabelWidth="82" TextBoxWidth="200" HorizontalAlignment="Left" LabelValue="{x:Static p:Strings.RomMD5Checksum}" TextBoxValue="{Binding MD5Checksum}"/>
</StackPanel>
DefaultLabelBox.cs
<UserControl x:Name="uc">
<StackPanel>
<TextBlock Text="{Binding Path=LabelValue, ElementName=uc}"
Width="{Binding Path=LabelWidth, ElementName=uc}"/>
<Label Content="{Binding Path=TextBoxValue, Mode=OneWay, ElementName=uc}"
Width="{Binding Path=TextBoxWidth, ElementName=uc}"/>
</StackPanel>
</UserControl>
DefaultLabelBox.xaml.cs
public string TextBoxValue
{
get {
return (string)GetValue(TextBoxValueProperty);
}
set {
SetValue(TextBoxValueProperty, value);
}
}
public static readonly DependencyProperty TextBoxValueProperty =
DependencyProperty.Register("TextBoxValue", typeof(string), typeof(DefaultLabelBox), new PropertyMetadata(default(string)));
コントロールテンプレート
<Style TargetType="dlb:DefaultLabelBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="dlb:DefaultLabelBox">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding LabelValue, RelativeSource={RelativeSource TemplatedParent}}"
MinWidth="20"
Width="{Binding LabelWidth, RelativeSource={RelativeSource TemplatedParent}}"
VerticalAlignment="Center"
FontFamily="Mangal"
Height="20"
FontSize="13"/>
<Label Content="{Binding TextBoxValue, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"
BorderBrush="{StaticResource DefaultLabelBoxBorderBrush}"
BorderThickness="1"
Padding="1,1,1,1"
Background="{StaticResource DefaultLabelBoxBackgroundBrush}"
Foreground="{StaticResource DefaultLabelBoxForeground}"
MinWidth="60"
Height="20"
VerticalAlignment="Center"
FontFamily="Mangal"
Width="{Binding TextBoxWidth, RelativeSource={RelativeSource TemplatedParent}}"
FontSize="13"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
私はいくつかのことを試みましたが、MVVMに新しくなりました。私にはバインディングのDataContextの問題があるかどうかわかりません。どんな助けもありがとう。
編集:私は忘れてしまったControlTemplateを追加するだけでなく、私のための解決策を説明するためにいくつかのコードを変更しました。私はMode = OneWayがUserControlとControlTemplateでは必須であるかどうかはわかりませんが、現在はそのまま動作していますのでそのまま残しています。
この上の最後の一日を過ごした後、私はあなたの提案を含め、私の作業溶液を、掲載しました。あなたは正しい道で私を送ってきましたが、私のバインディングにTemplatedParent RelativeSourceがなかったので、私は自分のControlTemplate(今編集した投稿)に問題がありました。どうもありがとう! – madsiur