1

我有几个包含数据库数据的列表。列表框用作图表的过滤器,列表框的外观应根据在其他列表框中选择的内容而改变。

这是我正在尝试做的一个简化示例:

Class Region
{
public int RegionID { get; set; }
public string RegionName { get; set; }
}

Class Country
{
public int CountryID { get; set; }
public string CountryName { get; set; }
public int RegionID { get; set; }
}

private void fillListBoxes()
{
List<Region> allRegions = getRegions();
lstRegionsFilter.ItemsSource = allRegions;
}

一个国家显然属于一个地区,我也有例如港口,然后位于一个国家等。

所有列表框项目都是这样定义的复选框:

<ListBox Name="lstRegionsFilter">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding Path=RegionName}"
                      Tag="{Binding Path=RegionID}" 
                      Click="CheckBox_Click"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

当单击任何列表框中的项目时,它们将被添加到过滤器列表中,该过滤器将过滤显示图表的数据。例如,如果在 Regions 下选择了“Europe”,那么所有属于欧洲的国家/地区都应该在国家/地区的列表框中以不同的颜色显示,例如蓝色。

因此,在代码中,我想遍历国家列表框中的复选框并将其前景色设置为取决于显示/标记到该复选框的值是否是属于所选区域的国家/地区,因此通常在 foreach 循环中。但是列表框中的项目是区域类型的,那么我如何访问底层复选框?这应该是我知道的非常基本的东西,但它让我发疯!

4

2 回答 2

1

尝试这个:

public class Region : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private bool isChecked;

    private void OnPropertyChaned(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public int RegionID { get; set; }
    public string RegionName { get; set; }

    public bool IsChecked
    {
        get { return isChecked; }
        set
        {
            if (isChecked != value)
            {
                isChecked = value;
                OnPropertyChaned("IsChecked");
            }
        }
    }
}

public class Country : INotifyPropertyChanged
{
    private readonly Region parentRegion;

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public Country(Region parent)
    {
        parentRegion = parent;
        parentRegion.PropertyChanged += ParentChanged;
    }

    private void ParentChanged(object sender, PropertyChangedEventArgs e)
    {
        if(e.PropertyName.Equals("IsChecked"))
        {
            OnPropertyChanged("IsParentChecked");
        }
    }

    public int CountryID { get; set; }
    public string CountryName { get; set; }
    public int RegionID { get { return parentRegion.RegionID; }}
    public bool IsParentChecked
    {
        get { return parentRegion.IsChecked; }
    }
}

和xml:

这是针对地区的:

<ListBox Name="lstRegionsFilter">
<ListBox.ItemTemplate>
    <DataTemplate>
        <CheckBox Content="{Binding Path=RegionName}"
                  Tag="{Binding Path=RegionID}"
                  IsChecked="{Binding Path=IsChecked}"
                  Click="CheckBox_Click"/>
    </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

这是给国家的

<ListBox Name="lstCountriesFilter">
<ListBox.ItemTemplate>
    <DataTemplate>
        <CheckBox ...
                  Foreground={Binding IsParentChecked, Converter={StaticResource boolToBrushConverter}"/>
                  ...
                  />
    </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

笔记:

  • 您需要实现 Converter 类(请参见此处
  • 将转换器作为 StaticResouce 添加到 xaml

如果区域 IsChecked 属性发生更改(来自 ui 或来自代码隐藏),则 Country Checkboxes 前景色将自动更改,因此不需要循环。

我没试过,可能你会发现错误,但我想展示“哲学”

希望能帮助到你

于 2012-06-29T11:52:32.237 回答
0

如果我猜对了,您的计划是如果选择了该地区,则在其地区颜色中突出显示一个国家/地区?Rq 1:您不必遍历复选框即可知道选择了哪个区域:这是绑定的目的,即绑定集合本身的值将受到影响。
Rq2 :如果您更改代码中的值,则必须在您的区域类中实现 INotifyPropertyChanged 才能更新 UI。
怎么做 ?
1. 有 RegionId --> Boolean 的静态字典。
2. 每当一个 RegionId 被选中/取消选中时,更新该字典并引发一个静态事件“SelectionDictionnaryUpdated”。
3. 现在在 Country 类中添加通知属性“IsOwnerRegionSelected”。它会在字典中查看是否选择了相应的区域。
4. 在您​​的 Country 类中添加属性“CountryRegionColor”。它将根据 RegionId 返回颜色,例如 RegionId -> Color 静态字典。
5. 在 DataTemplate 中添加一个触发器和一个 DataTrigger,它将根据 IsOwnerRegionSelected 值在白色和 CountryRegionColor 之间切换颜色。
6. 在一个国家的构造函数中,向 SelectionDictionnaryUpdated 添加一个处理程序,该处理程序将 NotifyPropertyChanged 放在“IsOwnerRegionSelected”上。

而已 !

  1. 您可以使用非共享字典(每个国家/地区都有一个 RegionId --> 您在构造函数中注入的布尔字典属性)
  2. 您可以通过使用 'CurrentCoulor': 通知属性来使事情变得更简单,该属性将返回白色或 CountryRegionColor,具体取决于它是否被选中。只需将列表的背景绑定到该属性,并在您捕获 SelectionDictionnaryUpdated 时更改 notifyCurrentCoulor。
于 2012-06-29T12:49:54.490 回答