【问题标题】:Binding data with WPF/C#使用 WPF/C# 绑定数据
【发布时间】:2021-05-24 09:58:08
【问题描述】:

我遇到了数据绑定问题(绑定更新?)。启动应用程序后,我加载图像并希望以 0-255 的比例显示它们的直方图。变量“频率”已经准备好数据。我想将它们绑定到 xaml 以显示某种图表。 XAML 代码可以很好地处理一些静态数据,但是将值分配给“频率”它不会显示任何内容。

XAML:

        <ItemsControl Name="ItemsControlName" ItemsSource="{Binding ChartValues}">
            <ItemsControl.DataContext>
                <local:DicomChart/>
            </ItemsControl.DataContext>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Rectangle Height="{Binding }" Width="4" VerticalAlignment="Bottom"
                   Fill="#eee" Stroke="Gray" Margin="-1.0"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

C#:

    private void RegionGrowing(object sender, RoutedEventArgs e)
    {
        int[] frequency = new int[256];

        for (int m = 0; m < 512; m++)
        {
            for (int n = 0; n < 512; n++)
            {
                frequency[database[pictureIndex, m, n]] += 1;
            }
        }

        DicomChart dc = new DicomChart();
        dc.ChartValues = frequency.ToArray();
    }

DicomClass 类:

public class DicomChart
{

    public DicomChart()
    {


    }

    public int[] ChartValues { get; set; }
    
}

【问题讨论】:

  • 您必须使用引发事件 CollectionChanged 的 ObservableCollection 才能在 WPF 中更新 UI。当您的 UI 被渲染并且数组绑定到 ItemsControl 时,它不知道它已更改。这就是需要 ObservableCollection 的地方。
  • 你的绑定应该像这样 ItemsSource="{Binding ChartValues, UpdateSourceTrigger=PropertyChanged}"
  • @DmitriyPolyanskiy 你的意思是把“public int[] ChartValues {get; set;}”改成“public ObservableCollection ChartValues {get; set;}”吗?
  • @tm607 是的!没错!
  • @DmitriyPolyanskiy 我试过这个,但它不起作用:(我也尝试使用 PropertyChangedEventHandler 但它也失败了

标签: c# wpf data-binding


【解决方案1】:

尝试使用像 DicomChartItem 这样的附加类并用它填充 observable 集合,类似的东西

C#:

public class DicomChart   
{
    public ObservableCollection<DicomChartItem> ChartItems{ get; set; } = new ObservableCollection<DicomChartItem>();
}
public class DicomChartItem
{
 public int _Value { get; set; }

    public DicomChartItem(int Value)
    {
        _Value = Value;
    }
}

XAML:

<ItemsControl ItemsSource="{Binding ChartItems}">
        <ItemsControl.DataContext>
            <local:DicomChart/>
        </ItemsControl.DataContext>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type local:DicomChartItem}">
                <Rectangle Height="{Binding _Value}" Width="4" VerticalAlignment="Bottom"
                   Fill="#eee" Stroke="Gray" Margin="-1.0"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

在调用CollectionChanged事件的循环中必须填充Observable集合,否则需要使用INotifyPropertyChanged接口的PropertyChanged事件。

C#:

private void RegionGrowing(object sender, RoutedEventArgs e)
    {
        int[] frequency = new int[256];

        for (int m = 0; m < 512; m++)
        {
            for (int n = 0; n < 512; n++)
            {
                frequency[database[pictureIndex, m, n]] += 1;
            }
        }

        DicomChart dc = new DicomChart();

        foreach (var item in frequency)
            dc.ChartItems.Add(new DicomChartItem(item));
    }

【讨论】:

  • 感谢您的回复,不幸的是该代码对我不起作用。我按照您的想法进行了一些操作,但仍然没有显示此图表
  • 尝试将在RegionGrowing方法中创建的DicomChart实例设置为UserControl的DataContext。我认为您的用户控件绑定到另一个 DicomChart 实例,没有项目。大概是这样。
  • 我想我把一切都安排好了。在“属性”(右下窗口)中,当我展开 DataContext 时,我会在它下面看到(Dicom Chart)和 ChartItems(Collection)。
  • 我的意思是在 RegionGrowing 中您创建了新的 DiconChart 对象,但您的 UserControl 绑定到另一个在应用程序启动时自动创建的对象(因为您在 XAML 标记中将其设置为 DataContext)。如果 RegionGrowing 方法位于您的 Window/Control 类中,请尝试执行以下操作:ItemsControlName.DataContext = dc,在创建并使用数据归档后。
  • 成功了,谢谢你的帮助,我很感激:)
【解决方案2】:
  1. 如我所说,您必须将 int[] 替换为 ObservableCollection&lt;int&gt;。它不适用于简单的数组,因为 UI 不会收到有关更改的通知。
  2. 将 x:Name="Items" 添加到您的 ItemsControl 以便能够从后面的代码中访问它;
  3. 在您的 RegionGrowing 中添加以下代码:var ds = (DicomChart) Items.DataContext;
  4. 向您的 ds 对象添加值,例如 ds.ChartValues.Add()。

【讨论】:

  • 感谢您的回答,您的解决方案也有效
猜你喜欢
  • 1970-01-01
  • 2011-10-29
  • 2017-03-12
  • 1970-01-01
  • 2013-08-23
  • 2013-07-25
  • 2012-01-22
  • 2013-10-05
  • 2011-03-18
相关资源
最近更新 更多