diff --git a/Tornado3_2026Election/MainWindow.xaml b/Tornado3_2026Election/MainWindow.xaml
index 79bb3fa..ccf6282 100644
--- a/Tornado3_2026Election/MainWindow.xaml
+++ b/Tornado3_2026Election/MainWindow.xaml
@@ -127,8 +127,10 @@
-
-
+
+
+
+
@@ -145,7 +147,12 @@
-
+
@@ -167,21 +174,73 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
IsCgConnected ? ConnectedStatusBrush : DisconnectedStatusBrush;
+ public Brush CgIntegrationCardBackgroundBrush => IsCgConnected ? ConnectedCardBackgroundBrush : DisconnectedCardBackgroundBrush;
+
+ public Brush CgIntegrationCardBorderBrush => CgIntegrationBrush;
+
+ public string CgIntegrationSignalText => IsCgConnected ? "CG 연결됨" : "CG 끊김";
+
+ public string CgIntegrationOperatorMessage => IsCgConnected ? "송출 가능" : "연결 확인 필요";
+
public Brush DataNavigationIconBrush => Data.HasLiveDataSignal
? DataReceivingNavigationBrush
: DataWaitingNavigationBrush;
+ public Brush SbsDataConnectionBrush => ResolveDataConnectionBrush(isMbcCni: false);
+
+ public Brush SbsDataConnectionCardBackgroundBrush => ResolveDataConnectionCardBackgroundBrush(isMbcCni: false);
+
+ public Brush SbsDataConnectionCardBorderBrush => SbsDataConnectionBrush;
+
+ public string SbsDataConnectionSummary => ResolveDataConnectionSummary(isMbcCni: false);
+
+ public string SbsDataConnectionDetail => ResolveDataConnectionDetail(isMbcCni: false);
+
+ public Brush MbcCniDataConnectionBrush => ResolveDataConnectionBrush(isMbcCni: true);
+
+ public Brush MbcCniDataConnectionCardBackgroundBrush => ResolveDataConnectionCardBackgroundBrush(isMbcCni: true);
+
+ public Brush MbcCniDataConnectionCardBorderBrush => MbcCniDataConnectionBrush;
+
+ public string MbcCniDataConnectionSummary => ResolveDataConnectionSummary(isMbcCni: true);
+
+ public string MbcCniDataConnectionDetail => ResolveDataConnectionDetail(isMbcCni: true);
+
public string CgIntegrationDetail
{
get
@@ -504,6 +544,93 @@ public sealed class MainViewModel : ObservableObject
public string HeaderStatus => $"{Settings.SelectedStation.Name} / {CurrentPageTitle} / {Data.BroadcastPhaseBadgeText} / {OperationModeLabel}";
+ private Brush ResolveDataConnectionBrush(bool isMbcCni)
+ {
+ if (!IsCurrentDataSource(isMbcCni))
+ {
+ return WaitingStatusBrush;
+ }
+
+ if (Data.IsRefreshing)
+ {
+ return ReceivingStatusBrush;
+ }
+
+ if (Data.HasLiveDataSignal)
+ {
+ return ConnectedStatusBrush;
+ }
+
+ return DisconnectedStatusBrush;
+ }
+
+ private Brush ResolveDataConnectionCardBackgroundBrush(bool isMbcCni)
+ {
+ if (!IsCurrentDataSource(isMbcCni))
+ {
+ return WaitingCardBackgroundBrush;
+ }
+
+ if (Data.IsRefreshing)
+ {
+ return ReceivingCardBackgroundBrush;
+ }
+
+ return Data.HasLiveDataSignal
+ ? ConnectedCardBackgroundBrush
+ : DisconnectedCardBackgroundBrush;
+ }
+
+ private string ResolveDataConnectionSummary(bool isMbcCni)
+ {
+ if (!IsCurrentDataSource(isMbcCni))
+ {
+ return "대기";
+ }
+
+ if (Data.IsRefreshing)
+ {
+ return "수신 중";
+ }
+
+ if (Data.HasLiveDataSignal)
+ {
+ return "연결됨";
+ }
+
+ if (!Data.IsCurrentApiSelectionSupported)
+ {
+ return "미지원";
+ }
+
+ return Data.LastRefreshAt == DateTimeOffset.MinValue ? "미수신" : "확인 필요";
+ }
+
+ private string ResolveDataConnectionDetail(bool isMbcCni)
+ {
+ if (!IsCurrentDataSource(isMbcCni))
+ {
+ return isMbcCni
+ ? "광역의원 포함 MBC CNI 데이터"
+ : "광역단체장 포함 SBS 데이터";
+ }
+
+ return $"{Data.ElectionType} / {Data.BroadcastPhaseLabel} / {Data.StatusText}";
+ }
+
+ private bool IsCurrentDataSource(bool isMbcCni)
+ {
+ return IsMbcCniDataSource(Data.ElectionType) == isMbcCni;
+ }
+
+ private static bool IsMbcCniDataSource(string electionType)
+ {
+ return string.Equals(electionType, "광역의원", StringComparison.Ordinal) ||
+ string.Equals(electionType, "기초의원", StringComparison.Ordinal) ||
+ string.Equals(electionType, "비례대표광역의원", StringComparison.Ordinal) ||
+ string.Equals(electionType, "비례대표기초의원", StringComparison.Ordinal);
+ }
+
public void Navigate(string tag)
{
var targetPage = tag switch
@@ -797,6 +924,17 @@ public sealed class MainViewModel : ObservableObject
OnPropertyChanged(nameof(DataNavigationIconBrush));
}
+ if (args.PropertyName is nameof(DataViewModel.HasLiveDataSignal)
+ or nameof(DataViewModel.IsRefreshing)
+ or nameof(DataViewModel.LastRefreshAt)
+ or nameof(DataViewModel.StatusText)
+ or nameof(DataViewModel.ElectionType)
+ or nameof(DataViewModel.BroadcastPhase)
+ or nameof(DataViewModel.IsPollingEnabled))
+ {
+ NotifyDataConnectionCardsChanged();
+ }
+
if (args.PropertyName is nameof(DataViewModel.IsPollingEnabled)
or nameof(DataViewModel.BroadcastPhase)
or nameof(DataViewModel.ElectionType)
@@ -812,11 +950,42 @@ public sealed class MainViewModel : ObservableObject
}
}
+ private void NotifyDataConnectionCardsChanged()
+ {
+ OnPropertyChanged(
+ nameof(DataNavigationIconBrush),
+ nameof(SbsDataConnectionBrush),
+ nameof(SbsDataConnectionCardBackgroundBrush),
+ nameof(SbsDataConnectionCardBorderBrush),
+ nameof(SbsDataConnectionSummary),
+ nameof(SbsDataConnectionDetail),
+ nameof(MbcCniDataConnectionBrush),
+ nameof(MbcCniDataConnectionCardBackgroundBrush),
+ nameof(MbcCniDataConnectionCardBorderBrush),
+ nameof(MbcCniDataConnectionSummary),
+ nameof(MbcCniDataConnectionDetail));
+ }
+
private void RestoreSelection_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
QueueAutomaticSave();
}
+ private void NotifyCgConnectionStatusChanged()
+ {
+ OnPropertyChanged(
+ nameof(IsCgConnected),
+ nameof(CgIntegrationSummary),
+ nameof(CgIntegrationBrush),
+ nameof(CgIntegrationCardBackgroundBrush),
+ nameof(CgIntegrationCardBorderBrush),
+ nameof(CgIntegrationSignalText),
+ nameof(CgIntegrationOperatorMessage),
+ nameof(CgIntegrationDetail),
+ nameof(TornadoConnectionSummary),
+ nameof(TornadoConnectionDetail));
+ }
+
private void Channel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName is nameof(ChannelScheduleViewModel.LoopEnabled)
@@ -829,13 +998,7 @@ public sealed class MainViewModel : ObservableObject
or nameof(ChannelScheduleViewModel.AdapterStateLabel)
or nameof(ChannelScheduleViewModel.IsCgConnected))
{
- OnPropertyChanged(
- nameof(IsCgConnected),
- nameof(CgIntegrationSummary),
- nameof(CgIntegrationBrush),
- nameof(CgIntegrationDetail),
- nameof(TornadoConnectionSummary),
- nameof(TornadoConnectionDetail));
+ NotifyCgConnectionStatusChanged();
}
}