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

C# 根据单击的按钮将字符串绑定到文本框,c#,.net,wpf,C#,.net,Wpf,我有一个编辑器(文本框),我想根据点击的按钮绑定不同的文本 我可以在按钮上使用命令,通过commandparameter传递我想要编辑的字符串,并更新绑定到文本框的字符串。这会起作用,但不会保存修改,因为文本(通过commandparameter传递)和文本框的文本之间没有绑定 我的问题是,在不直接从视图模型访问文本框的情况下,我应该如何巧妙地实现这个绑定 编辑:我想要达到的目标可能很模糊。我试着澄清一下: 假设我有几个不同的按钮,如果我点击其中一个,它会将一些字符串绑定到编辑器的文本框中,在那

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

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

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

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

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

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

     <Button Content="Edit query" Command="{Binding ShowQueryInEditorCommand}" CommandParameter="{Binding SomeOtherSqlStringToBeEdited}"/>
以及编辑器文本框本身:

    <TextBox Text="{Binding SQLStatement}">


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

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

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

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

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

根据

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

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 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将被选中时,列表框项目也将被选中。 第三,从所选项目的背景中隐藏所选内容


希望,这会有帮助。

你能至少发布一个按钮和文本框的代码吗?谢谢我喜欢你的Xaml方法,但问题是按钮是动态创建的,我想不出一种方法来解决这个问题,有什么建议吗?关于代码隐藏解决方案,SQLStatement就是你描述的“DisplayText”或“SelectedText”。我不知道的是将SomeSqlStringToBeedite绑定到SQLStatement的逻辑。你能修改一下我上面的代码吗?我可能错过了一些非常简单的东西,但我不知道它是什么。谢谢你,丹尼斯,从外观上看,这是一个非常好和整洁的解决方案。我设法以不同的方式解决了这个问题,也许没有你那么好,但在我的特殊情况下效果很好。因为这可能对其他有类似问题的人有用,所以我将标记您的完整解决方案作为答案。谢谢
<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}" />