struct的一種用法

孤沉發表於2024-10-09

今天開啟程式發現不對勁,三個按鈕顯示一樣的Content。
查詢程式碼,發現問題出現在

private void InitMenuData()
{
    HomeMenuItem menuItem = new HomeMenuItem();
    var dict = menuItem.ReadUnityConfig("MenuConfiguration");
    foreach (var item in dict.Values)
    {
        menuItem.Value = item;
        Pages.Add(menuItem);
    }
}

class是引用傳遞
所以HomeMenuItem新增的過程中,只新增了最後一個選項
將HomeMenuItem改為struct完美解決,
下面奉上全部程式碼

<ListBox
    x:Name="list"
    Height="40"
    ItemsSource="{Binding Pages}"
    Style="{DynamicResource StackPanelHorizontalListBox}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border  BorderThickness="1">
                <DockPanel LastChildFill="True">
                    <Button
                        Height="32" Width="80"
                        Command="{s:Action ExecuteNavigatToView}"
                        CommandParameter="{Binding NavigatToView}"
                        Content="{Binding Value}" />
                </DockPanel>
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
public class HomeViewModel: Screen
{      
    private BindableCollection<HomeMenuItem> _pages;

    public BindableCollection<HomeMenuItem> Pages
    {
        get => _pages??(_pages=new BindableCollection<HomeMenuItem>());
        set => SetAndNotify(ref _pages, value);
    }

    public HomeViewModel()
    {
        InitMenuData();
    }

    private void InitMenuData()
    {
        HomeMenuItem menuItem = new HomeMenuItem();
        var dict = menuItem.ReadUnityConfig("MenuConfiguration");
        foreach (var item in dict.Values)
        {
            //HomeMenuItem menuItem = new HomeMenuItem();        //使用struct的好處是這裡是值傳遞,不需要重新構造資料
            menuItem.Value = item;
            Pages.Add(menuItem);
        }
    }
}
 public struct HomeMenuItem
 {
     public string Key { get; set; }
     public string Value { get; set; }

     public string NavigateToView { get; set; }

     /// <summary>
     /// 重置
     /// </summary>
     public void ResetItem()
     {
         this=new HomeMenuItem();
     }
 }

 public static class HomeMenuItemExtension
 {
     /// <summary>
     /// 讀取WPF自帶的App.config
     /// 這兩個引用沒有傳遞值,是讀取config的值,所以不需要使用ref,
     /// 使用了struct後,如果傳遞資料的擴充套件方法,需要加上ref
     /// </summary>
     /// <param name="menuList"></param>
     public static Dictionary<string, string> ReadAppConfig(this HomeMenuItem menuList, string section)
     {
         IDictionary idict = (IDictionary)ConfigurationManager.GetSection(section);
         Dictionary<string, string> dict = idict.Cast<DictionaryEntry>().ToDictionary(de => de.Key.ToString(), de => de.Value.ToString());
         return dict;
     }

     /// <summary>
     /// 讀取自定義的config檔案
     /// </summary>
     /// <param name="menuList"></param>
     public static Dictionary<string, string> ReadUnityConfig(this HomeMenuItem menuList, string section)
     {
         Dictionary<string, string> dicts = new Dictionary<string, string>();
         ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap
         {
             ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"unity.config")
         };

         Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

         var customSection = (MenuConfiguration)config.GetSection(section);
         foreach (MenuElement menu in customSection.Menus)
         {
             dicts.TryAdd(menu.Title, menu.Value);
         }
         return dicts;

     }
 }
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<configSections>
		<section name="MenuConfiguration" type="IgniteApp.Common.MenuConfiguration,IgniteApp" />
	</configSections>
	<MenuConfiguration>
		<menus>
			<add title="001" value="標題1"/>
			<add title="002" value="標題2"/>
			<add title="003" value="標題3"/>
		</menus>
	</MenuConfiguration>
</configuration>
</unity>-->

相關文章