Compare commits

...

4 Commits

Author SHA1 Message Date
Hack茶ん
131fe71205 Update Korean translation (#624) 2025-02-05 02:40:37 -06:00
Evan Husted
6af388c623 misc: chore: [ci skip] oops forgot to localize the reset button & confirmation 2025-02-05 02:01:33 -06:00
Evan Husted
45cec4e7cf UI: In-app Configuration resetting 2025-02-05 01:42:27 -06:00
FluffyOMC
479b38f035 Add tooltips to game status (#625) 2025-02-05 00:42:20 -06:00
8 changed files with 281 additions and 49 deletions

View File

@@ -584,7 +584,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "UI를 숨긴 상태에서 게임 시작",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -2259,7 +2259,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "PPTC 캐시 제거",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -2284,7 +2284,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "앱의 모든 PPTC 캐시 파일 삭제",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -2609,7 +2609,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "선택한 DLC 파일에서 RomFS 추출",
"no_NO": "Pakk ut RomFS filene fra valgt DLC fil", "no_NO": "Pakk ut RomFS filene fra valgt DLC fil",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -2759,7 +2759,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "호환성 항목 표시",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -2784,7 +2784,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "일반적으로 도움말 메뉴를 통해 접근할 수 있는 호환성 목록에 선택한 게임을 표시합니다.",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -2809,7 +2809,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "게임 통계 표시",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -2834,7 +2834,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "그리드 보기 레이아웃에서 누락된 현재 선택된 게임에 대한 다양한 정보를 표시합니다.",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -3609,7 +3609,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "Aggiornamenti e DLC che fanno riferimento a file mancanti verranno disabilitati automaticamente", "it_IT": "Aggiornamenti e DLC che fanno riferimento a file mancanti verranno disabilitati automaticamente",
"ja_JP": "", "ja_JP": "",
"ko_KR": "누락된 파일을 참조하는 DLC 및 업데이트가 자동으로 언로드", "ko_KR": "누락된 파일을 참조하는 DLC 및 업데이트가 자동으로 불러오기 취소",
"no_NO": "DLC og oppdateringer som henviser til manglende filer, vil bli lastet ned automatisk", "no_NO": "DLC og oppdateringer som henviser til manglende filer, vil bli lastet ned automatisk",
"pl_PL": "", "pl_PL": "",
"pt_BR": "DLCs e Atualizações que se referem a arquivos ausentes serão descarregadas automaticamente", "pt_BR": "DLCs e Atualizações que se referem a arquivos ausentes serão descarregadas automaticamente",
@@ -4384,7 +4384,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "스웨덴어",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -4409,7 +4409,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "노르웨이어",
"no_NO": "Norsk", "no_NO": "Norsk",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -4484,7 +4484,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "매치 시스템 시간",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -6122,6 +6122,56 @@
"zh_TW": "關閉" "zh_TW": "關閉"
} }
}, },
{
"ID": "SettingsButtonReset",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Reset Settings",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "SettingsButtonResetConfirm",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "I want to reset my settings.",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{ {
"ID": "SettingsButtonOk", "ID": "SettingsButtonOk",
"Translations": { "Translations": {
@@ -8034,7 +8084,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "비활성화",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -8059,7 +8109,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "레인보우",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -8084,7 +8134,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "레인보우 속도",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -8109,7 +8159,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "색상",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -13359,7 +13409,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "다음에서 모든 PPTC 데이터를 제거하려고 합니다:\n\n{0}\n\n계속하시겠습니까?",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -19359,7 +19409,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "LED 설정",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -22284,7 +22334,7 @@
"he_IL": "ממשק רשת", "he_IL": "ממשק רשת",
"it_IT": "Interfaccia di rete:", "it_IT": "Interfaccia di rete:",
"ja_JP": "ネットワークインタフェース:", "ja_JP": "ネットワークインタフェース:",
"ko_KR": "네트워크 인터페이스:", "ko_KR": "네트워크 인터페이스 :",
"no_NO": "Nettverksgrensesnitt", "no_NO": "Nettverksgrensesnitt",
"pl_PL": "Interfejs sieci:", "pl_PL": "Interfejs sieci:",
"pt_BR": "Interface de rede:", "pt_BR": "Interface de rede:",
@@ -23259,7 +23309,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "최종 업데이트 : {0}",
"no_NO": "Sist oppdatert: {0}", "no_NO": "Sist oppdatert: {0}",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -23497,6 +23547,131 @@
"zh_TW": "無法啟動" "zh_TW": "無法啟動"
} }
}, },
{
"ID": "CompatibilityListPlayableTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Boots and plays without any crashes or GPU bugs of any kind, and at a speed fast enough to reasonably enjoy on an average PC.",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "CompatibilityListIngameTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Boots and goes in-game but suffers from one or more of the following: crashes, deadlocks, GPU bugs, distractingly bad audio, or is simply too slow. Game still might able to be played all the way through, but not as the game is intended to play.",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "CompatibilityListMenusTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Boots and goes past the title screen but does not make it into main gameplay.",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "CompatibilityListBootsTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Boots but does not make it past the title screen.",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "CompatibilityListNothingTooltip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Does not boot or shows no signs of activity.",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{ {
"ID": "ExtractAocListHeader", "ID": "ExtractAocListHeader",
"Translations": { "Translations": {
@@ -23509,7 +23684,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "추출할 DLC 선택",
"no_NO": "Velg en DLC og hente ut", "no_NO": "Velg en DLC og hente ut",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -23523,4 +23698,4 @@
} }
} }
] ]
} }

View File

@@ -41,13 +41,12 @@
HorizontalAlignment="Left" HorizontalAlignment="Left"
Orientation="Vertical" Orientation="Vertical"
Spacing="5"> Spacing="5">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal" IsVisible="{Binding AppData.HasPlayabilityInfo}">
<TextBlock Padding="0, 0, 5, 0" Text="{ext:Locale GameListHeaderCompatibilityStatus}" /> <TextBlock Padding="0, 0, 5, 0" Text="{ext:Locale GameListHeaderCompatibilityStatus}" />
<Button <Button
Click="PlayabilityStatus_OnClick" Click="PlayabilityStatus_OnClick"
HorizontalContentAlignment="Left" HorizontalContentAlignment="Left"
VerticalAlignment="Center" VerticalAlignment="Center"
IsVisible="{Binding AppData.HasPlayabilityInfo}"
Background="{DynamicResource AppListBackgroundColor}" Background="{DynamicResource AppListBackgroundColor}"
Padding="0"> Padding="0">
<TextBlock <TextBlock
@@ -55,6 +54,7 @@
Tag="{Binding AppData.IdString}" Tag="{Binding AppData.IdString}"
Text="{Binding AppData.LocalizedStatus}" Text="{Binding AppData.LocalizedStatus}"
Foreground="{Binding AppData.PlayabilityStatus, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}" Foreground="{Binding AppData.PlayabilityStatus, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
ToolTip.Tip="{Binding AppData.LocalizedStatusTooltip}"
TextAlignment="Start" TextAlignment="Start"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<Button.Styles> <Button.Styles>

View File

@@ -93,7 +93,8 @@
IsVisible="{Binding HasPlayabilityInfo}" IsVisible="{Binding HasPlayabilityInfo}"
Background="{DynamicResource AppListBackgroundColor}" Background="{DynamicResource AppListBackgroundColor}"
Margin="-1, 0, 0, 0" Margin="-1, 0, 0, 0"
Padding="0" > Padding="0"
ToolTip.Tip="{Binding LocalizedStatusTooltip}">
<TextBlock <TextBlock
Margin="1.5" Margin="1.5"
Tag="{Binding IdString}" Tag="{Binding IdString}"

View File

@@ -2,7 +2,7 @@ using Avalonia.Collections;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Threading; using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Gommon; using CommunityToolkit.Mvvm.Input;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.OpenAL;
using Ryujinx.Audio.Backends.SDL2; using Ryujinx.Audio.Backends.SDL2;
@@ -28,8 +28,6 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using TimeZone = Ryujinx.Ava.UI.Models.TimeZone; using TimeZone = Ryujinx.Ava.UI.Models.TimeZone;
@@ -722,6 +720,25 @@ namespace Ryujinx.Ava.UI.ViewModels
CloseWindow?.Invoke(); CloseWindow?.Invoke();
} }
[ObservableProperty] private bool _wantsToReset;
public AsyncRelayCommand ResetButton => Commands.Create(async () =>
{
if (!WantsToReset) return;
CloseWindow?.Invoke();
ConfigurationState.Instance.LoadDefault();
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
RyujinxApp.MainWindow.LoadApplications();
await ContentDialogHelper.CreateInfoDialog(
$"Your {RyujinxApp.FullAppName} configuration has been reset.",
"",
string.Empty,
LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
"Configuration Reset");
});
public void CancelButton() public void CancelButton()
{ {
RevertIfNotSaved(); RevertIfNotSaved();

View File

@@ -108,24 +108,36 @@
</Style> </Style>
</ui:NavigationView.Styles> </ui:NavigationView.Styles>
</ui:NavigationView> </ui:NavigationView>
<ReversibleStackPanel <Grid Grid.Row="2"
Grid.Row="2" ColumnDefinitions="Auto,*,Auto">
Margin="10" <StackPanel Grid.Column="0" Orientation="Horizontal">
Spacing="10" <Button
Orientation="Horizontal" IsEnabled="{Binding WantsToReset}"
HorizontalAlignment="Right" Margin="10"
ReverseOrder="{x:Static helper:RunningPlatform.IsMacOS}"> Content="{ext:Locale SettingsButtonReset}"
<Button Command="{Binding ResetButton}" />
Classes="accent" <CheckBox IsChecked="{Binding WantsToReset}"/>
Content="{ext:Locale SettingsButtonOk}" <TextBlock Text="{ext:Locale SettingsButtonResetConfirm}"/>
Command="{Binding OkButton}" /> </StackPanel>
<Button <ReversibleStackPanel
HotKey="Escape" Grid.Column="2"
Content="{ext:Locale SettingsButtonCancel}" Margin="10"
Command="{Binding CancelButton}" /> Spacing="10"
<Button Orientation="Horizontal"
Content="{ext:Locale SettingsButtonApply}" HorizontalAlignment="Right"
Command="{Binding ApplyButton}" /> ReverseOrder="{x:Static helper:RunningPlatform.IsMacOS}">
</ReversibleStackPanel> <Button
Classes="accent"
Content="{ext:Locale SettingsButtonOk}"
Command="{Binding OkButton}" />
<Button
HotKey="Escape"
Content="{ext:Locale SettingsButtonCancel}"
Command="{Binding CancelButton}" />
<Button
Content="{ext:Locale SettingsButtonApply}"
Command="{Binding ApplyButton}" />
</ReversibleStackPanel>
</Grid>
</Grid> </Grid>
</window:StyleableAppWindow> </window:StyleableAppWindow>

View File

@@ -46,7 +46,19 @@ namespace Ryujinx.Ava.Utilities.AppLibrary
: string.Empty; : string.Empty;
public LocaleKeys? PlayabilityStatus { get; set; } public LocaleKeys? PlayabilityStatus { get; set; }
public string LocalizedStatusTooltip =>
PlayabilityStatus.HasValue
#pragma warning disable CS8509 // It is exhaustive for any value this property can contain.
? LocaleManager.Instance[PlayabilityStatus!.Value switch
#pragma warning restore CS8509
{
LocaleKeys.CompatibilityListPlayable => LocaleKeys.CompatibilityListPlayableTooltip,
LocaleKeys.CompatibilityListIngame => LocaleKeys.CompatibilityListIngameTooltip,
LocaleKeys.CompatibilityListMenus => LocaleKeys.CompatibilityListMenusTooltip,
LocaleKeys.CompatibilityListBoots => LocaleKeys.CompatibilityListBootsTooltip,
LocaleKeys.CompatibilityListNothing => LocaleKeys.CompatibilityListNothingTooltip,
}]
: string.Empty;
public int PlayerCount { get; set; } public int PlayerCount { get; set; }
public int GameCount { get; set; } public int GameCount { get; set; }

View File

@@ -100,12 +100,25 @@ namespace Ryujinx.Ava.Utilities.Compat
public Optional<string> TitleId { get; } public Optional<string> TitleId { get; }
public string[] Labels { get; } public string[] Labels { get; }
public LocaleKeys? Status { get; } public LocaleKeys? Status { get; }
public LocaleKeys? StatusDescription
=> Status switch
{
LocaleKeys.CompatibilityListPlayable => LocaleKeys.CompatibilityListPlayableTooltip,
LocaleKeys.CompatibilityListIngame => LocaleKeys.CompatibilityListIngameTooltip,
LocaleKeys.CompatibilityListMenus => LocaleKeys.CompatibilityListMenusTooltip,
LocaleKeys.CompatibilityListBoots => LocaleKeys.CompatibilityListBootsTooltip,
LocaleKeys.CompatibilityListNothing => LocaleKeys.CompatibilityListNothingTooltip,
_ => null
};
public DateTime LastUpdated { get; } public DateTime LastUpdated { get; }
public string LocalizedLastUpdated => public string LocalizedLastUpdated =>
LocaleManager.FormatDynamicValue(LocaleKeys.CompatibilityListLastUpdated, LastUpdated.Humanize()); LocaleManager.FormatDynamicValue(LocaleKeys.CompatibilityListLastUpdated, LastUpdated.Humanize());
public string LocalizedStatus => LocaleManager.Instance[Status!.Value]; public string LocalizedStatus => LocaleManager.Instance[Status!.Value];
public string LocalizedStatusDescription => LocaleManager.Instance[StatusDescription!.Value];
public string FormattedTitleId => TitleId public string FormattedTitleId => TitleId
.OrElse(new string(' ', 16)); .OrElse(new string(' ', 16));

View File

@@ -64,6 +64,8 @@
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{Binding LocalizedStatus}" Text="{Binding LocalizedStatus}"
Width="85" Width="85"
Background="Transparent"
ToolTip.Tip="{Binding LocalizedStatusDescription}"
Foreground="{Binding Status, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}" Foreground="{Binding Status, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
TextWrapping="NoWrap" /> TextWrapping="NoWrap" />
<TextBlock Grid.Column="3" <TextBlock Grid.Column="3"