简体   繁体   中英

Bind Dictionary<string, double> entries to a XAML number textblock WPF

In my XAML file, I have a 3rd party (syncfusion) DoubleTextBox control:

<syncfusion:DoubleTextBox x:Name="personAHeight" Style="{StaticResource SFDoubleTB}" />

When the DoubleTextBox loses focus, it copies the value to a Dictionary that I have created (the XAML element and the dictionary key have the exact same name), in order to save the keys and values to use on another page.

public static Dictionary<string, double> globalDictionary = new Dictionary<string, double>()
{
        {"personAHeight", 0}, {"personBHeight", 0},
        // over 100 keys & values
}

When a DoubleTextBox loses focus (this has been set in styles):

void SFTextBox_LostFocus(object sender, RoutedEventArgs e)
    {
        var tb1 = sender as DoubleTextBox;

        if ((double) tb1.Value != 0)
        {
            if (App.globalDictionary.ContainsKey(tb1.Name))
            {
                App.globalDictionary[tb1.Name] = (double) tb1.Value;              // always replace the value                  
            }
            else
            {
                App.globalDictionary.Add(tb1.Name, (double) tb1.Value);           // add the entry to the dictionary in app.xaml.cs                 
            }               
        }
    }

All of this works as expected. I am also able to save the globalDictionary using JSON serialization to a text file, using the SaveFileDialog, and then open the file again and de-serialize it.

private void saveProject_Click(object sender, RoutedEventArgs e)
{
        SaveFileDialog saveFileDialog = new SaveFileDialog();

        if(saveFileDialog.ShowDialog() == true)
        {                                 
            string jsonString = App.SerializeToJSONString();
            File.WriteAllText(saveFileDialog.FileName, jsonString);
        }
}

Open File:

private void openProject_Click(object sender, RoutedEventArgs e)
{
        OpenFileDialog openFileDialog = new OpenFileDialog();
        if (openFileDialog.ShowDialog() == true)
        {
            string stringToDeserialize = File.ReadAllText(openFileDialog.FileName);
            App.DeserializeJSONString(stringToDeserialize);

           // read this data and then put the value back into XAML number box
        }
}

Deserialize JSON String

public static void DeserializeJSONString(string jsonString)
    {
        App.globalDictionary = JsonConvert.DeserializeObject<Dictionary<string, double>>(jsonString);
    }

All the values from the saved file are successfully written back to the globalDictionary.

My question now is, after the file is open and the contents read, is there an easy way to put those contents back into the number text box through automatically iterating through each XAML element? The user should automatically see that all the values have been restored.

The brute force way is to do the following after opening the file. If possible, I'd prefer not to do it, since I have over 100 elements.

personAHeight.Value = App.globalDictionary["personAHeight"];
...repeat x 100

Any alternate suggestions will be appreciated.

Why not put your 100+ DoubleTextBox controls inside Listbox and define these DoubleTextBox as Data Template? Such as :

 <ListBox x:Name="myListBox">
        <ListBox.ItemTemplate>
            <WrapPanel>
            <Label Content={Binding Key}
            <syncfusion:DoubleTextBox Style="{StaticResource SFDoubleTB}" Value={Binding Value}/>
            </WrapPanel>
        </ListBox.ItemTemplate>
    </ListBox>

And then set binding to your dictionary in the code after load:

myListBox.ItemsSource=App.globalDictionary; 
public void RestoreValues()
{   
    var controlContainer = VisualTreeHelper.GetChild(???, ???) as FrameworkElement;
    if (controlContainer != null)
    {
        foreach (var keyValuePair in App.globalDictionary)
        {
            var doubleTextBox = controlContainer.FindName(keyValuePair.key) as syncfusion:DoubleTextBox;
            if (doubleTextBox != null)
                doubleTextBox.Value = keyValuePair.Value;
         }
     }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM