gpt4 book ai didi

c# - Databinding ItemsControl (DataTemplate) 不更新/只在程序启动时接收值

转载 作者:太空狗 更新时间:2023-10-29 23:52:21 24 4
gpt4 key购买 nike

EDIT2:填充图表后,我无法再更改这些值。即使我更改列表中的值(ItemControls 从中获取值),图表似乎也不会更新为新值。

我调用计时器中的 GetDataGrafiek() 方法每 x 秒更新一次我的图表。

        Grafiek graf = new Grafiek();
graf.GetDataGrafiek();

这是由于线程计时器在单独的线程中运行(IsAsynchronous 中的 ObjectDataProvider 方法)还是我需要访问 DataContext我的计时器方法中的 ItemsControl?

编辑:当程序已经运行时我无法填充图表所以我制作了ObservableCollection<GrafiekBar>静态(包含柱的填充和值的列表)和初始化如下:

public static ObservableCollection<GrafiekBar> listGrafiek = new ObservableCollection<GrafiekBar>()
{
new GrafiekBar() {Value = 0, Fill = (Brush)convertor.ConvertFromString(kleuren[0])},
new GrafiekBar() {Value = 0, Fill = (Brush)convertor.ConvertFromString(kleuren[1])},
new GrafiekBar() {Value = 0, Fill = (Brush)convertor.ConvertFromString(kleuren[2])}
};

来自 MSDN:ObjectDataProvider:“但是,如果您要绑定(bind)到一个已经创建的对象,则需要在代码中设置 DataContext,如下例所示。”


我有一个显示为简单条形图的 ItemsControl。当我分配值时(在我的代码隐藏中进行硬编码),图表会成功填充。

我所做的基本上是获取最大值,将其设置为 100%,并通过该值计算其余条形的长度。

问题:我不希望对图表条形值进行硬编码,但条形图必须更改运行时间。为此,我使用 Threading.Timer只要我的程序正在运行,它就会每秒运行一次(其他计算也会在此计时器中进行)。

图表栏值根据此计时器内每 x 秒发生的计算进行更新。

我已经尝试了所有方法,但在我的程序运行时无法显示值。当我对它们进行硬编码时,我只能看到条形图(请参阅线程末尾的 GetDataGrafiek() 区域)。我到底做错了什么/错过了什么?

GetDataGrafiek() (用于填充我的图表的计算)在 ObjectDataProvider 中被调用.

此方法将 TimeSpan 作为输入,然后执行计算,因此我得到一个 double 值(基于上面解释的 100% 值),然后将其放置在条形值(= 日期模板的宽度)中。

<ObjectDataProvider x:Key="odpLbGrafiek" ObjectType="{x:Type myClasses:GrafiekBar}" MethodName="GetDataGrafiek"/>

我的 ItemsControl 的 DataTemplate(这使用 Width 作为我图表条形的值)

<DataTemplate x:Key="GrafiekItemTemplate">
<Border Width="Auto" Height="Auto">
<Grid>
<Rectangle StrokeThickness="0" Height="30"
Margin="15"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="{Binding Value}"
Fill="{Binding Fill}">
<Rectangle.LayoutTransform>
<ScaleTransform ScaleX="20" />
</Rectangle.LayoutTransform>
</Rectangle>
</Grid>
</Border>
</DataTemplate>

项目控制:

 <ItemsControl x:Name="icGrafiek"  
Margin="50,3,0,0"
ItemsSource="{Binding Source={StaticResource odpLbGrafiek}}"
ItemTemplate="{DynamicResource GrafiekItemTemplate}"
RenderTransformOrigin="1,0.5" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.RowSpan="6">
<ItemsControl.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1" ScaleX="1"/>
<SkewTransform AngleY="0" AngleX="0"/>
<RotateTransform Angle="180"/>
<TranslateTransform/>
</TransformGroup>
</ItemsControl.RenderTransform>
</ItemsControl>

GetDataGrafiek() 该区域保存硬编码值,完成后我的图表成功显示 6 个柱。当我评论该区域时,我不再看到任何可见的条。

此方法返回一个列表 Double值。每个值代表一个条,在 DataTemplate 中表示为宽度, 而 Fill 只是给它一种特定的颜色。

ObservableCollection<GrafiekBar> listGrafiek = new ObservableCollection<GrafiekBar>();

public ObservableCollection<GrafiekBar> GetDataGrafiek()
{
var converter = new System.Windows.Media.BrushConverter();

#region ***TEST HARDCODED BAR VALUES***
int[] testWaardenUren = new int[] { 2, 1, 0, 1, 2, 0 };
int[] testWaardenMinuten = new int[] { 58, 2, 55, 55, 2, 20 };

for (int j = 0; j < 6; j++)
{
TimeSpan ts = new TimeSpan(testWaardenUren[j], testWaardenMinuten[j], 0);
GlobalObservableCol.regStilstanden[j].Value = ts;
GlobalObservableCol.regStilstanden[j].Name = "";
}
#endregion

totalMinutesMaxValue = GetLargestValueStilstanden(); //= "100%" value

//calculate % of stilstanden Values
for (int i = 0; i < GlobalObservableCol.regStilstanden.Count; i++)
{
Double totalMin = GlobalObservableCol.regStilstanden[i].Value.TotalMinutes;
totalMin = totalMin / totalMinutesMaxValue * 10;
valuesChartPercentage.Add(totalMin);
}

//the barChart (itemsControl) gets its final values here
for (int j = 0; j < GlobalObservableCol.regStilstanden.Count; j++)
{
GrafiekBar bar = new GrafiekBar();
bar.Value = valuesChartPercentage[j];
bar.Fill = converter.ConvertFromString(kleuren[j]) as Brush;
listGrafiek.Add(bar);
}

return listGrafiek;
}

GrafiekBar.cls

 public class GrafiekBar : INotifyPropertyChanged
{
private double value;
private Brush fill;

public GrafiekBar()
{
}

public double Value
{
get { return this.value; }

set
{
this.value = value;
NotifyPropertyChanged("Value");
}
}

public Brush Fill
{
get { return this.fill; }

set
{
this.fill = value;
NotifyPropertyChanged("Fill");
}
}

//interface INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;

//interface INotifyPropertyChanged
private void NotifyPropertyChanged(String info)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}

每秒运行一次的线程计时器(具有计算逻辑和在那里调用的 getDataGrafiek() 调用 GUI 线程进行更新。

private void MyTimerCallBack(object state)
{
DisplayWegingInfo();

App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() =>
{
//actions that involve updating the UI
CaculateTimeBetweenWegingen();
}));
}

最好的问候彼得。

最佳答案

这是在黑暗中开枪,因为我没有通读你所有的代码,但有一个想法:你正在绑定(bind)到静态资源,对吧?它被读取一次,就是这样,嗯?请改用 DynamicResource。

关于c# - Databinding ItemsControl (DataTemplate) 不更新/只在程序启动时接收值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10281014/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com