根据数据库中的某些数据绑定listboxitem的背景颜色
Posted
技术标签:
【中文标题】根据数据库中的某些数据绑定listboxitem的背景颜色【英文标题】:Binding background color of listboxitem depending on certain data from the database 【发布时间】:2020-10-20 13:27:10 【问题描述】:我正在 wpf 中尝试根据某些特定规则为背景着色。我用绑定试过这个,但它不起作用。
我有 2 个区域和 16 个位置,如下所示:
A.ItemsSource = Enumerable.Range(1, 16);
B.ItemsSource = Enumerable.Range(1, 16);
2 areas with 16 locations
在 backgroundWorker_DoWork 中,如果我有“打开”的东西,我会查看数据库,如果有,我会通过 A.Dispatcher.BeginInvoke (System.Windows.Threading.DispatcherPriority.Normal, UpdateMyDelegate, mystring2, mystring1);
发送
到主线程2个字符串代表区域和位置。
我有(在 MainWindow.cs 中):
private void UpdateMyDelegateListbox (int mystring2, string mystring1)
if (mystring1 == "A")
A.SelectedItem = mystring2;
VM.Background1 = something like new string () or bool somehow ??
else if (mystring1 == "B") ...
这个想法是检查哪个位置是开放的或“被阻止”color it red
我只想绑定。我现在做的是这个(xaml):
<Style x:Key="SimpleListBoxItem" TargetType="ListBoxItem">
<!--<Setter Property="FocusVisualStyle" Value="x:Null"/>-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border" Padding="2" SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<!--<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="Yellow"/>
</Trigger>-->
**<DataTrigger Binding="Binding Success" Value="True">
<Setter TargetName="Border" Property="Background" Value="Green"/>
</DataTrigger>**
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
每个区域都在一个堆栈面板中,并且都在一个滚动查看器中
例如:
<!-- Area A -->
<ScrollViewer HorizontalScrollBarVisibility="Disabled" Grid.Row="1" VerticalScrollBarVisibility="Disabled" Height="500" VerticalAlignment="Top" Margin="0,10,0,-8" >
<WrapPanel Width="2000" Height="500">
<StackPanel Width="500" Height="500">
<ListBox x:Name="A" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Margin="10,10,85,85" SelectionMode="Multiple" ItemContainerStyle="DynamicResource SimpleListBoxItem" SelectionChanged="listboxA_SelectionChanged" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel ItemHeight="100"
ItemWidth="100"
Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate DataType="local:TestApp">
<StackPanel Margin="20" HorizontalAlignment="Center">
<Viewbox>
<Grid x:Name="backgroundGrid"
Width="48"
Height="48">
<Rectangle x:Name="Rect" Fill="Orange" />
<Label HorizontalContentAlignment="Center"
Content="Binding"
FontFamily="Segoe UI"
FontSize="24"
Foreground="White" />
</Grid>
</Viewbox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
在 ViewModel 我有:
class TestAppViewModel: INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged = (sender, e) => ;
private void RaisePropertyChanged(string prop)
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
public object _background => null;
public string Background1
get
return Background1;
set
if (_background == value)
return;
Background1 = value;
RaisePropertyChanged("Background");
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Background1)));
我想使用像 IsOccupied 这样的东西来主要传输,如果在区域 y 的位置 x 有东西然后变成红色,否则留下橙色。我想实时看到谁忙谁空。
如果您能给我任何建议,我将不胜感激。谢谢你,对任何类型的错误感到抱歉,但我很着急发帖。 :)
【问题讨论】:
如果您只有一个Background1
属性,您应该如何更改单个项目的背景?或者Background1
在哪里定义?您如何使用TestAppViewModel
?
【参考方案1】:
您应该将ItemsSource
设置为具有决定背景的属性的对象集合:
A.ItemsSource = Enumerable.Range(1, 16).Select(x => new TestAppViewModel(x));
将int
属性添加到TestAppViewModel
类:
class TestAppViewModel : INotifyPropertyChanged
public TestAppViewModel(int number)
Number = number;
public event PropertyChangedEventHandler PropertyChanged = (sender, e) => ;
private void RaisePropertyChanged(string prop)
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
public int Number get;
public object _background;
public string Background1
get
return Background1;
set
if (_background == value)
return;
_background = value;
RaisePropertyChanged("Background1");
并绑定到模板中的源属性:
<ListBox.ItemTemplate>
<DataTemplate DataType="local:TestApp">
<StackPanel Margin="20" HorizontalAlignment="Center">
<Viewbox>
<Grid x:Name="backgroundGrid"
Width="48"
Height="48">
<Rectangle x:Name="Rect" Fill="Binding Background1" />
<Label HorizontalContentAlignment="Center"
Content="Binding Number"
FontFamily="Segoe UI"
FontSize="24"
Foreground="White" />
</Grid>
</Viewbox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
【讨论】:
【参考方案2】:我在 ViewModel 中生成了一个构造函数,以便能够使用私有 PickByLightViewModel VM = new PickByLightViewModel();
,然后使用数字绑定成功,但没有填充。
这里有TestApp:
namespace TestApp
public partial class MainWindow : Window
private TestAppViewModel VM = new TestAppViewModel ();
private static BackgroundWorker backgroundWorker;
public MainWindow()
InitializeComponent();
A.ItemsSource = Enumerable.Range(1, 16).Select(x => new TestAppViewModel (x));
B.ItemsSource = Enumerable.Range(1, 16).Select(x => new TestAppViewModel (x));
C.ItemsSource = Enumerable.Range(1, 16).Select(x => new TestAppViewModel (x));
D.ItemsSource = Enumerable.Range(1, 16).Select(x => new TestAppViewModel (x));
Application.Current.MainWindow.WindowState = WindowState.Maximized;
backgroundWorker = new BackgroundWorker
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
;
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
backgroundWorker.RunWorkerAsync();
private delegate void UpdateMyDelegatedelegate(int mystring2, string mystring1);
private void UpdateMyDelegateListbox(int mystring2, string mystring1)
if (mystring1 == "A")
A.SelectedIndex = mystring2;
VM.Background1 = "Red";
else if (mystring1 == "B")...
是的,你是对的,非常感谢你的解释。
我做了一些更改,但如果我使用例如:VM.Background1 = "Red";
,它仍然无法正常工作,如果我这样做绑定,那么我会收到 *** 异常。
【讨论】:
以上是关于根据数据库中的某些数据绑定listboxitem的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章
WPF:如何使用 MVVM 将命令绑定到 ListBoxItem?
根据 ListBox 中的索引设置 ListBoxItem 的样式