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