안녕하세요. 간단하게 풀어볼려고 해도 안 풀려서 질문드리게 되었습니다…ㅠ
public async Task NextLoadtodasmmisalarmDB()
{
if (setotime != null)
{
try
{
connString = "host=localhost;Port=5432;Username=postgres;Password=dkenc;Database=mmis;";
string query = $@"Select * From to_das_mmi_alarm where otime > @Setotime Order by otime desc";
using (var conn = new NpgsqlConnection(connString))
{
await conn.OpenAsync();
using (var cmd = new NpgsqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("@Setotime", setotime);
using (var reader = await cmd.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
var otime = reader.GetDateTime(0);
var alarm = new to_das_mmi_alarm()
{
Otime = otime,
Name = reader.GetString(1),
Value = reader.GetDouble(2),
A_tag_no = reader.GetString(3),
State = reader.GetBoolean(4),
Description = reader.GetString(5),
Source_sys_name = reader.GetString(6),
};
setotime = otime;
updatedAlarms.Insert(0, alarm);
// 버튼용 구조체 만들기 아래는!
// 알람을 추가하거나 업데이트하기 전에 A_tag_no 기준으로 검색
var existingAlarm = updatedAlarms2.FirstOrDefault(a => a.A_tag_no == alarm.A_tag_no);
if (existingAlarm != null)
{
// 이미 존재하는 알람의 otime이 새 알람의 otime보다 이전인 경우 업데이트
if (existingAlarm.Otime < alarm.Otime)
{
var updatedAlarm = new to_das_mmi_alarm()
{
Otime = alarm.Otime,
Name = alarm.Name,
Value = alarm.Value,
A_tag_no = alarm.A_tag_no,
State = alarm.State,
Description = alarm.Description,
Source_sys_name = alarm.Source_sys_name,
Isview = alarm.Isview,
};
var index = updatedAlarms2.IndexOf(existingAlarm);
if (index != -1)
{
updatedAlarms2[index] = updatedAlarm;
}
}
}
else
{
// 새 A_tag_no의 알람이면 그냥 추가
updatedAlarms2.Add(alarm);
}
}
}
}
}
Dispatcher.Invoke(() =>
{
qwe.ItemsSource = updatedAlarms2;
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
public void SetupTimer()
{
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += Timer_Tick;
_timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
foreach (var alarm in updatedAlarms)
{
alarm.Isview = !alarm.Isview; // 현재 값의 반대로 설정
}
}
저의 질문에 관련된 핵심 코드라고 생각되는 것을 올립니다.
to_das_mmi_alarm 클래스는 ObservableCollection타입이며, INotifyPropertyChanged가 구현되어있는 상태입니다.
isview라는 칼럼은 to_das_mmi_alarm 클래스에서 설정해둔 bool타입 변수입니다.
의도한 것은 1초마다 타이머에 의해 true,false로 값이 변동이 되고, 디버깅하여 잘 작동하는 것을 확인하였습니다.
DB에서 받아온 값들을 전체 조회하고 꾸준히 누적시켜서 쌓는 구조체가 UpdatedAlarms입니다.
이 UpdatedAlarms에서 a_tag_no별 최신시간별 한개의 행만을 가지고 있는 것이 UpdatedAlarms2입니다.
코드를 실행하여 외부기기로부터 값이 꾸준히 DB에 쌓이게 되고, 이 DB의 데이터는 UpdatedAlarms에 전체 누적으로 쌓입니다.
UpdatedAlarms2에는 a_tag_no별로 최신시간에 해당하는 값이 들어오면 존재하던 행이 대체되어 매핑이 됩니다.
여기서 오류가 발생합니다.
초기 실행시에는 무리 없이 updatedAlarms2에서 updatedAlarms의 isview칼럼의 값을 가져옵니다. true,false로 꾸준히 변동되는 값을 매핑해서 가져옵니다.
그러나 새로운 값이 들어와 값이 대체되게 되면, 그때 당시에 해당하는 값을 가져올 뿐, 주기성으로 바뀌는 값에 대해서는 반응을 하지 못합니다.
저는 꾸준히 주기성으로 바뀌는 isview의 값(true,false)을 가져오고 싶습니다.
제가 시도해본 작업으론
- isview = updatedAlarms[1].Isview; 로 바꾸어 직접참조 (?)도 해보았고,
- 타이머 메서드에서 foreach문을 하나 더 만들어 사용도 해보았습니다.
위와 같이 변경해볼려고 하였는데 잘 안되었습니다. 혹시 좋은 방법이 있는지 알려주시면 너무 너무 감사하겠습니다 ㅜ!
private void Timer_Tick(object sender, EventArgs e)
{
foreach (var alarm in updatedAlarms2)
{
alarm.Isview = !alarm.Isview; // 현재 값의 반대로 설정
}
}
요로케 바꾸면 제가 원하는 기능은 제대로 작동하지만,저는 근본적으로 하나의 전역 값(?)을 여러 구조체에서 공통적으로 참조하고 싶습니다.
알려주시면 열심히 찾아보고 배우겠습니다 ㅜ