2

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

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

我的问题是,我应该如何在不直接从视图模型访问文本框的情况下巧妙地实现此绑定?

编辑:我想要实现的目标可能很模糊。我试着澄清一下:

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

     <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。这就是我想要实现的,在单击按钮时以某种方式将该字符串绑定到文本框。

4

2 回答 2

2

我能想到的基本方法有两种:通过代码或通过 Xaml。

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

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

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

于 2012-08-10T08:17:39.773 回答
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 将被选中时,列表框项目也将被选中。第三隐藏所选项目背景的选择。

希望这可以帮助。

于 2012-08-10T09:43:06.927 回答