将TextBox.TextProperty绑定到Model中Binding类型的属性

时间:2012-11-19 16:38:06

标签: wpf mvvm

我有一个命令按钮列表(带输入)我想与模型绑定。 问题是我希望按钮中的文本框能够绑定到某个地方(参见viewmodel)。

以下代码是我尝试过但失败的代码。 (甚至)是否可以在模型上设置绑定然后将其绑定到控件?

或者换句话说,我是想尝试以愚蠢的方式做事吗?

查看:

<ToolBar Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="0" ItemsSource="{Binding SelectedTab.Commands}" Height="34">
    <ToolBar.Resources>
        <DataTemplate DataType="{x:Type model:ZoekCommandButtons}">
            <Button Command="{Binding Command}" ToolTip="{Binding Tooltip}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding Image, Converter={StaticResource ImageConv}}" Height="16" Width="16"></Image>
                    **<TextBox Width="100" Text="{Binding Text}">**
                        <TextBox.InputBindings>
                            <KeyBinding Gesture="Enter" Command="{Binding Command}"></KeyBinding>
                        </TextBox.InputBindings>
                    </TextBox>
                </StackPanel>
            </Button>
        </DataTemplate>
    </ToolBar.Resources>
</ToolBar>

型号:

    public class ZoekCommandButtons : BaseModel, ICommandItem
    {
        private string _header;
        private string _image;
        private bool _isEnabled;
        private Visibility _isVisible;
        private ICommand _command;
        private string _tooltip;
        private Binding _text;


        public Binding Text
        {
            get { return _text; }
            set { _text = value; OnPropertyChanged("Text"); }
        }
(etc)

视图模型:

    Commands.Add(new ZoekCommandButtons()
    {
        Image = "search.png",
        IsEnabled = true,
        **Text = new Binding { RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(UserControl), 1), Path = new PropertyPath("FilterText") },**
        Command = FilterCommand,
        Tooltip = "Zoeken",
        Header = "Zoeken"
    });

2 个答案:

答案 0 :(得分:3)

首先,我建议将Binding公开为ViewModel属性;在这种特殊情况下,对我来说听起来更像是嵌套了ViewModel,而且这种方法更合适 - 也就是说,你有一个“MamaViewModel”,它具有你的“Commands”属性,而这又是“CommandButtonViewModels”的集合......

好的,那说......你可以这样做,虽然我必须重申你可能;你所缺少的是“评估绑定的东西”来提供价值。这是一个给你的课程:

public static class BindingEvaluator
{
    // need a DP to set the binding to
    private static readonly DependencyProperty PlaceholderProperty = 
        DependencyProperty.RegisterAttached("Placeholder", typeof(object), typeof(DependencyObject), new UIPropertyMetadata(null));

    // Evaluate a binding by attaching it to a dummy object/property and evaluating the property value
    public static object Evaluate(Binding binding)
    {
        var throwaway = new DependencyObject();
        BindingOperations.SetBinding(throwaway, PlaceholderProperty, binding);
        var retVal = throwaway.GetValue(PlaceholderProperty);
        return retVal;
    }
}

结合ViewModel定义,如:

public class DontDoThisViewModel
{
    public Binding TextBinding {get; set;}
    public string Text 
    {
        get 
        {
            return BindingEvaluator.Evaluate(TextBinding) as string;
        }
    }
}

应该工作......这是我在LINQPad中一起投入的测试应用程序:

void Main()
{
    var wnd = new Window() { Title = "My window" };
    var text = new TextBlock();
    text.Text = "Hopefully this shows the window title...";
    text.SetBinding(TextBlock.TextProperty, new Binding("Text"));
    wnd.Content = text;
    var vm = new ViewModel();
    var vmBinding = new Binding("Title");
    vmBinding.Source = wnd;
    vm.TextBinding = vmBinding;
    wnd.DataContext = vm;
    wnd.Show();
}

再次,我必须强烈建议你这样做......但我很好奇,所以我不得不想方设法。 ;)

答案 1 :(得分:0)

确定。我没有直接思考。

将Model中的Text属性更改为string并使用此属性处理命令。

(虽然以某种方式在模型上设置绑定会很好......)