1

この方法で親コントロールで使用される UserControl があります。

<Views:TranslationTextInput  Translation="{Binding SelectedEntity.Name}"/>

親コントロールの DataContext は、SelectedEntity プロパティを含む ViewModel です。

子 UserControl で、新しい ViewModel を DataContext として定義します。

    <UserControl.DataContext>
      <vm:TranslationTextInputViewModel x:Name="vm"></vm:TranslationTextInputViewModel>
    </UserControl.DataContext>

私が持っているコードの背後にある:

    public static readonly  DependencyProperty TranslationProperty = DependencyProperty.Register("Translation", typeof(Translation),typeof(UserControl));

    // .NET Property wrapper
    public Translation Translation
    {
        get { return (Translation)GetValue(TranslationProperty); }
        set { SetValue(TranslationProperty, value); }
    }


 public TranslationTextInput(){
     InitializeComponent();
     DataContext = new TranslationTextInputViewModel();
     SetBinding(TranslationProperty,   new Binding { Path = new PropertyPath     ("Translation"), Mode = BindingMode.OneWayToSource });

実行すると、Binding エラーが発生します。

System.Windows.Data Error: 40 : BindingExpression path error: 'SelectedEntity' property not found on 'object' ''TranslationTextInputViewModel' (HashCode=49954236)'. BindingExpression:Path=SelectedEntity.Name; DataItem='TranslationTextInputViewModel' (HashCode=49954236); target element is 'TranslationTextInput' (Name='InputControl'); target property is 'Translation' (type 'Translation')

SelectedEntity は子 UserControl の Viewmodel で検索されているようですが、親 ViewModel の Property を使用する必要があります。どうすればこれを解決できますか?

編集:

    public TranslationTextInputViewModel()
    {
        //EnglishTranslation = tranlsations["en"];
    }

    public string EnglishTranslation
    {
        get
        {
            if (!Translation.TranslationDict.ContainsKey(new CultureInfo("en").LCID))
                Translation.Translations.Add(new TranslationItem() { Text = "", Lcid = new CultureInfo("en").LCID });
            return Translation.TranslationDict[new CultureInfo("en").LCID].Text;
        }
        set
        {
            Translation.TranslationDict[new CultureInfo("en").LCID].Text = value;
        }

    }

    public string SelectedTranslation
    {
        get
        {
            if (!Translation.TranslationDict.ContainsKey(_selectedLanguage))
                Translation.Translations.Add(new TranslationItem() { Text = "", Lcid = _selectedLanguage });
            return Translation.TranslationDict[_selectedLanguage].Text;

        }

        set
        {
            Translation.TranslationDict[_selectedLanguage].Text = value;
        }
    }

    private Translation _translation;

    public Translation Translation
    {
        get
        {
            if (_translation == null)
                _translation = new Translation();
            return _translation; }
        set { _translation = value; }
    }

    private int _selectedLanguage;
    public int SelectedLanguage
    {
        get
        {
            return _selectedLanguage;
        }
    }

    public List<CultureInfo> AvailableLanguages
    {
        get
        {

            return (from x in PqsLocalization.AvailableLanguages where x.Name != "en" select x).ToList();
        }
    }

    public RelayCommand<int> LanguageChanged { get; private set; }


    private void LanguageChangedExecute(int lang)
    {
        _selectedLanguage = lang;
        RaisePropertyChanged("SelectedLanguage");
        RaisePropertyChanged("SelectedTranslation");
    }
4

4 に答える 4

4

の内側からDataContextのを設定するべきではありません。そうすることで、他のユーザーがに渡されるのを防ぐことができます。これは、UIレイヤーとデータレイヤーを分離するというWPFの最大の利点の1つを打ち負かします。UserControlUserControlDataContextUserControl

UserControlが作成されているときは、DataContextを新しいTranslationTextInputViewModelに設定しTranslationTextInputViewModelていて、というプロパティがないSelectedEntityため、バインディングは失敗します。

私のおすすめ?DataContextにを設定しないでくださいUserControl

特定のViewModelを特定のUserControlに使用する場合は、それをに追加して、次ParentViewModelのようにとして渡しますDataContext

<Window.Resources>
    <DataTemplate DataType="{x:Type vm:TranslationTextInputViewModel}">
        <Views:TranslationTextInput />
    </DataTemplate>
</Window.Resources>

またはこれ:

<Views:TranslationTextInput 
    DataContext="{Binding SelectedTranslationTextInputViewModel}" />

または、それ自体にViewModel固有の機能が含まれていてUserControl、アプリケーションレイヤーの一部であってはならない場合は、そのコードをコードビハインドに配置しUserControlViewModel完全に削除します。

于 2012-10-10T13:05:14.257 に答える
1

バインディングを設定DataContextするとそれが使用されるので、この動作を期待します-を探しSelectedEntity.NameますTranslationTextInputViewModel

これを機能させるにはいくつかの方法があります。個人的には、これらの関係をビューモデル自体(ビューモデルプロパティを持つビューモデル)でモデル化するのが好きですが、この状況では、おそらくこれを試してみて、不快に感じます。

<Views:TranslationTextInput 
    Translation="{Binding DataContext.SelectedEntity.Name,
                  RelativeSource={RelativeSource FindAncestor,
                                  AncestorType=ParentControlType}}" />
于 2012-10-10T12:22:28.470 に答える
1

これを試して:

<Views:TranslationTextInput  Translation="{Binding SelectedEntity.Name}" DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" /> 
于 2012-10-10T12:18:41.833 に答える
0

これは、コンストラクターでTranslationTextInput.DataContextTranslationTextInputViewModelに設定したためです。

于 2012-10-10T12:20:05.577 に答える