C# 如何在wpf中单击按钮时更新文本框背景色
我有两个文本框,其中包含C# 如何在wpf中单击按钮时更新文本框背景色,c#,.net,wpf,mvvm,C#,.net,Wpf,Mvvm,我有两个文本框,其中包含rollnumber和name,并包含在列表框中。我有一个按钮,每次点击都会在文本框中添加数据 我想实现的是,当我点击按钮时,它必须将两个文本框的背景色都更改为绿色。(请记住,每次单击此按钮时,我都会有一个新行,它会在两个文本框中添加一些文本) 我试着使用触发器,但还没成功。代码如下: <Window.Resources> <Style x:Key="buttonColorChange" TargetType="{x:Type Butt
rollnumber
和name
,并包含在列表框中。我有一个按钮,每次点击都会在文本框中添加数据
我想实现的是,当我点击按钮时,它必须将两个文本框的背景色都更改为绿色。(请记住,每次单击此按钮时,我都会有一个新行,它会在两个文本框中添加一些文本)
我试着使用触发器,但还没成功。代码如下:
<Window.Resources>
<Style x:Key="buttonColorChange" TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding Click, ElementName=btnClick}" Value="true">
<Setter Property="Background" Value="Green"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ListBox Name="empLB" ItemsSource="{Binding Path=emp}" Height="100" Width="300" VerticalAlignment="Top">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel Width="300" >
<TextBox Name="txt2" Text="{Binding Path= RollNo}"></TextBox>
<TextBox Name="txt1" Text="{Binding Path=Name}"></TextBox>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Style="{StaticResource buttonColorChange}" Name="btnClick" Height="20" Width="100" Content="click On me" Command="{Binding BtnClick}" ></Button>
</Grid>
如何将按钮单击时文本框的颜色更改为绿色?与评论员一样,我也将该逻辑放入ViewModel中。这里有一个例子。我正在使用GalaSoft.MvvmLight nuget包 查看XAML:
<Window.Resources>
<local:BoolToBrushConverter x:Key="boolToColorConv" />
</Window.Resources>
<Grid>
<ListBox Name="empLB" ItemsSource="{Binding Path=emp}" Height="100" Width="300" VerticalAlignment="Top">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel Width="300" >
<TextBox Name="txt2"
Text="{Binding Path= RollNo}"
Background="{Binding Path=DataContext.ContainsItems,
Converter={StaticResource boolToColorConv},
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}} }" />
<TextBox Name="txt1"
Text="{Binding Path=Name}"
Background="{Binding Path=DataContext.ContainsItems,
Converter={StaticResource boolToColorConv},
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}} }" />
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Name="btnClick" Height="20" Width="100" Content="click On me" Command="{Binding BtnClick}" />
</Grid>
视图模型:
public class RollsViewModel : ViewModelBase
{
public ObservableCollection<Item> emp
{
get;
set;
}
public bool ContainsItems
{
get { return _containsItems; }
set { _containsItems = value; RaisePropertyChanged(); }
}
private bool _containsItems;
public RollsViewModel()
{
emp = new ObservableCollection<Item>();
}
public ICommand BtnClick
{
get
{
if (_btnClick == null)
{
_btnClick = new RelayCommand(() =>
{
// Dummy action, replace with call to model
emp.Add(new Item() { Name = "A roll", RollNo = emp.Count });
ContainsItems = emp.Count > 0;
});
}
return _btnClick;
}
}
private RelayCommand _btnClick;
}
public class Item : ViewModelBase
{
public int RollNo
{
get { return _rollNo; }
set { _rollNo = value; RaisePropertyChanged(); }
}
private int _rollNo;
public string Name
{
get { return _name; }
set { _name = value; RaisePropertyChanged(); }
}
private string _name;
}
一种简单的方法是将背景颜色绑定到字符串变量,并在单击按钮
string color=“Green”
按钮时对其进行更改,但该按钮不包含Click属性,因此该样式内的绑定不会产生任何效果。除此之外,如果要更改文本框的背景,则应将样式指定给文本框,而不是按钮。正如上面所说,在viewmodel中有一个属性,并直接从文本框绑定到它。因为该属性不在您的列表中,所以您需要在此处使用relativesource绑定。谢谢您的回答。如果您能解释一下为什么我们需要在这里使用相对资源绑定,那就太好了?仅仅通过样式和触发器就可以实现吗?我是说点击按钮会触发文本框的样式改变?你说呢?相对绑定是必要的,因为我们需要在层次结构级别(伪代码)上进行操作:-Window.DataContext(和Window.Grid.DataContext)被设置为RollsViewModel-Window.ListBox.ItemsSource被设置为RollsViewModel.emp-Window.ListBox.Item[x]。数据模板中的文本框绑定到RollsViewModel.emp[x].RollNo或.Name属性,但文本框应绑定到的containsSitems属性是RollsViewModel本身的成员。通过进入网格(RelativeSource是FindAncestor,类型为Grid),可以绑定到网格的DataContext,即RollViewModel。我不确定是否无法使用样式和触发器在不同的GUI元素中更改某件事,但我对此表示怀疑。样式的目的是,它的设计可以应用于您想要的任何按钮,而不仅仅是一个按钮。如果您想要的是可能的,那么如果样式应用于视图中的多个按钮,那么哪个文本框的背景应该设置为绿色?如果可能,则是一个问题。但另一个问题是,文本框的颜色最好放在哪里。它只是一个GUI的东西吗?(例如,简单地向用户指示他单击了按钮。)然后我将其放置在ViewModel中,如示例所示。在MVVM中,视图应该拥有尽可能少的代码。视图的逻辑应该位于其ViewModel逻辑中。还是一种商业逻辑?然后,当BtnClick命令进入模型时,您应该遵循该命令。模型逻辑将更改某些内容,并且该更改应传播到ViewModel中。
public class RollsViewModel : ViewModelBase
{
public ObservableCollection<Item> emp
{
get;
set;
}
public bool ContainsItems
{
get { return _containsItems; }
set { _containsItems = value; RaisePropertyChanged(); }
}
private bool _containsItems;
public RollsViewModel()
{
emp = new ObservableCollection<Item>();
}
public ICommand BtnClick
{
get
{
if (_btnClick == null)
{
_btnClick = new RelayCommand(() =>
{
// Dummy action, replace with call to model
emp.Add(new Item() { Name = "A roll", RollNo = emp.Count });
ContainsItems = emp.Count > 0;
});
}
return _btnClick;
}
}
private RelayCommand _btnClick;
}
public class Item : ViewModelBase
{
public int RollNo
{
get { return _rollNo; }
set { _rollNo = value; RaisePropertyChanged(); }
}
private int _rollNo;
public string Name
{
get { return _name; }
set { _name = value; RaisePropertyChanged(); }
}
private string _name;
}
public class BoolToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var color = (value is bool && (bool)value) ? System.Windows.Media.Colors.Green : System.Windows.SystemColors.ControlColor;
return new SolidColorBrush(color);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}