使用datatemplate将视图传递给viewmodel

时间:2010-05-17 16:51:12

标签: wpf mvvm binding datatemplate

我有一个名为ParameterEditorView的窗口,ParameterEditorViewModelDataContext。在ParameterEditorViewModel我有一个ParameterViewModel列表。在ParameterEditorView我有一个ItemsControl,其ItemsSource被绑定到ParameterViewModelParameterEditorViewModel的列表。我需要ParameterViewModel来引用ParameterView(稍后会详细介绍)。在Resources的{​​{1}}部分,我添加了ParameterEditorView

DataTemplate

那么,我如何传递<DataTemplate DataType="{x:Type my:ParameterViewModel}" > <my:ParameterView HorizontalAlignment="Left"/> </DataTemplate> 的引用来创建ParameterView来显示ParameterViewModel

我需要ParameterViewParameterViewModel的原因如下: 我有一个TextBox,其Text属性绑定到PropertyModelView.Name属性。但是我希望在Name为空或空时显示默认字符串。我曾尝试将属性值设置为我想要的默认字符串,但在此方案中未设置TextBox.Text。我做这样的事情:

private string _name;
public string Name
{
    get { return _name; }
    set
    {
        if (value == null || value.Length == 0)
            Name = _defaultName;
        else
            _name = value;
    }
}

我还试图将TextBox.Text绑定模式专门设置为TwoWay而没有成功。 我认为这是防止无限循环发生的防御机制,但我不确定。 在这方面的任何帮助也将受到高度赞赏。

谢谢, JoséTavares

1 个答案:

答案 0 :(得分:1)

{Binding } has a FallbackValue, btw.

你的问题,这让我很困惑。我假设您的PVM有一个PV集合作为公共属性,它绑定在UI中。另外,我认为你是混合术语。它的Model-View-ViewModel,其中ViewModel是View的DataContext,ViewModel通过公共属性公开Model。听起来如果你将窗口绑定到ViewModel集合,它们实际上是模型。它可能看起来很迂腐,但让你的条款正确可以帮助你研究和提问。

另一个解决方案是将一个转换器与FallbackValue一起添加到Binding中(我必须这样做,IIRC)。该转换器将是一个IValueConverter,如果字符串为null或为空,则返回“DependencyProperty.UnsetValue”。我认为这有时会起作用,因为如果TB为空,TextBox会将bound属性设置为空字符串而不是null。这里有一个小样品来鞭打你的哨子(不能保证工作;你需要调试它并调整它):

public class ThisMightWorkConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, System.Globalization.CultureInfo culture)
    {
        var temp = value as string;
        if(string.IsNullOrWhiteSpace(temp))
            return System.Windows.DependencyProperty.UnsetValue;
        return temp;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, System.Globalization.CultureInfo culture)
    {
        return value; // you might need to change this
    }
}