根据单击的按钮将字符串绑定到文本框

时间:2012-08-10 08:06:40

标签: c# .net wpf

我有一个编辑器(文本框),我想根据点击的按钮将不同的文本绑定到它。

我可以在按钮上使用命令并通过命令参数传递我想编辑的字符串,并更新绑定到文本框的字符串。这将有效,但它不会保存修改,因为文本(通过命令参数传递)和文本框的文本之间没有绑定。

我的问题是,如果不直接从View模型访问文本框,我应该如何巧妙地实现此绑定?

编辑:我想要达到的目标可能很模糊。我试着澄清一点:

所以,假设我有几个不同的按钮,如果我点击其中一个,它应该将一些字符串绑定到编辑器的文本框,我可以在其中修改它并稍后保存。

     <Button Content="Edit query" Command="{Binding ShowQueryInEditorCommand}" CommandParameter="{Binding SomeSqlStringToBeEdited}"/>

     <Button Content="Edit query" Command="{Binding ShowQueryInEditorCommand}" CommandParameter="{Binding SomeOtherSqlStringToBeEdited}"/>

这是命令将执行的内容:

    public void ShowQueryInEditor(object o)
    {            
        string SqlStatementParam = o as string;
        if (SqlStatementParam != null)
            SQLStatement = SqlStatementParam;            
    }

编辑器TextBox本身:

    <TextBox Text="{Binding SQLStatement}">

正如您所看到的,这是非常基本的,因为它只是设置SQLStatement字符串,但它们之间没有绑定,因此它无法将修改反映回SomeSqlStringToBeEdited / SomeOtherSqlStringToBeEdited。这就是我想要实现的,在单击按钮时以某种方式将该字符串绑定到文本框。

2 个答案:

答案 0 :(得分:2)

我可以想到两种基本方式:通过代码,或通过Xaml。

在代码中,不是从ViewModel访问文本框,而是在ViewModel中为“DisplayText”或“SelectedText”添加一个新属性,或者在您的场景中添加任何有意义的属性。将文本框绑定到该属性,然后将所需的其余逻辑放在setter中(或者,如果它是DependencyProperty,则为OnPropertyChanged回调)。这保留了ViewModel中的所有逻辑,意味着Xaml不必关心。

或者在Xaml中,您可以使用触发器和模板根据所选按钮更改文本框。最有可能形成您的描述,我建议使用多个文本框,一个绑定到每个字符串,并根据单击的按钮切换可见文本框。这使ViewModel无法忽略此特定于显示的逻辑,并允许您稍后更轻松地更改它。

就个人而言,我可能会建议使用Xaml方法,但这取决于您的具体情况。

答案 1 :(得分:0)

根据

  

但问题是按钮是动态创建的

1)将查询文本和按钮包装到视图模型中,如下所示:

public class ViewModel : ViewModelBase
{
    public ViewModel()
    {
        this.turnIsSelectedOnCommand = new RelayCommand(() => IsSelected = true);
    }

    public String Text
    {
        get { return text; }
        set
        {
            if (text != value)
            {
                text = value;
                OnPropertyChanged("Text");
            }
        }
    }
    private String text;

    public Boolean IsSelected
    {
        get { return isSelected; }
        set
        {
            if (isSelected != value)
            {
                isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }
    }
    private Boolean isSelected;

    public RelayCommand TurnIsSelectedOnCommand
    {
        get { return turnIsSelectedOnCommand; }
    }
    private readonly RelayCommand turnIsSelectedOnCommand;
}

2)将动态创建的文本/按钮放入集合中。为简单起见,我已将它们添加到数组中:

    public MainWindow()
    {
        InitializeComponent();
        DataContext = new[] 
        { 
            new ViewModel { Text = "SELECT * FROM Foo", IsSelected = true },
            new ViewModel { Text = "SELECT * FROM Bar" },
            new ViewModel { Text = "DROP TABLE Foo" },
            new ViewModel { Text = "DROP TABLE Bar" },
        };
    }

3)使用ListBox和编辑器绑定集合 - 使用所选项目的Text

<ListBox Grid.Row="0" Margin="5" ItemsSource="{Binding}" x:Name="lbItems">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Right"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                                 Color="Transparent"/>
            </Style.Resources>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Button Content="Edit query" Command="{Binding TurnIsSelectedOnCommand}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

<TextBox Grid.Row="1" Margin="5" Text="{Binding Path=SelectedItem.Text, ElementName=lbItems}" />

我添加了一些样式修改。 首先修改按钮布局。 第二个意思是,当您按下按钮并且ViewModel将被选中时,也将选择列表框项目。 第三个从所选项目的背景中隐藏选择。

希望,这有帮助。