根据数据库中的某些数据绑定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的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

获取ListBox中的ListBoxItem

WPF:如何使用 MVVM 将命令绑定到 ListBoxItem?

在加载时动画ListBoxItem

根据 ListBox 中的索引设置 ListBoxItem 的样式

ListBoxItem 与 ListViewItem 的 GridViewColumn 绑定

一般拖放 ListBoxItems