简体   繁体   中英

Custom method in user control

I have a usercontrol (ItemPairing) that includes two comboboxes and one button. I know that I can override the ToString() method, but what I want to do is create a custom method that returns an array or dictionary. The combobox items are supplied when the control is generated so those are getting passed in as parameters to the initialization. The application will be adding multiple ItemPairing controls (user can add and remove ItemPairing controls to fit their needs) and then iterating over all ItemPairing controls when the user clicks a Run button.

If there is an easier way to do this please let me know. The general idea is to let the user dynamically build paired items and then combine each pair into a single dictionary when they click run.

ItemPairing XAML:

<UserControl x:Class="TableComparisons.ItemPairing"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         x:Name="ItemPairingName"
         mc:Ignorable="d" 
         d:DesignHeight="24" d:DesignWidth="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="24"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="24"/>
    </Grid.RowDefinitions>
    <ComboBox Grid.Row="0" Grid.Column="0" x:Name="Table1_Fields" SelectionChanged="Table1_Fields_SelectionChanged">
    </ComboBox>
    <ComboBox Grid.Row="0" Grid.Column="1" x:Name="Table2_Fields" SelectionChanged="Table2_Fields_SelectionChanged">
    </ComboBox>
    <Button Grid.Row="0" Grid.Column="2" Content="X" Click="Button_Click" />
</Grid>

ItempPairing C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TableComparisons
{
public partial class ItemPairing : UserControl
{
    public string selectExpr = "None";
    public string fields1 = "";
    public string fields2 = "";

    public override string ToString()
    {
        return selectExpr;
    }

    private void updateSE()
    {
        selectExpr = this.fields1 + " = " + this.fields2;
    }

    public ItemPairing()
    {
        InitializeComponent();
        List<string> listFields_1 = new List<string>();
        listFields_1.Add("One");
        listFields_1.Add("Two");
        listFields_1.Add("Three");
        listFields_1.Add("Four");
        Table1_Fields.ItemsSource = listFields_1;

        List<string> table2Fields = new List<string>();
        table2Fields.Add("A");
        table2Fields.Add("B");
        table2Fields.Add("C");
        table2Fields.Add("D");

        Table2_Fields.ItemsSource = table2Fields;
    }

    public ItemPairing(List<string> table1Fields, List<string> table2Fields)
    {
        InitializeComponent();
        Table1_Fields.ItemsSource = table1Fields;
        Table2_Fields.ItemsSource = table2Fields;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        ((Panel)this.Parent).Children.Remove(this);
    }

    private void Table1_Fields_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        fields1 = this.Table1_Fields.SelectedValue.ToString();
        updateSE();
    }
    private void Table2_Fields_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        fields2 = this.Table2_Fields.SelectedValue.ToString();
        updateSE();
    }
}
}

Adding child ItemPairing:

UIElement pi2 = new ItemPairing(table1Fields, table2Fields);
ParingItems.Children.Add(pi2);

Iterating over ItemPairing controls:

private void runPairing_Click(object sender, RoutedEventArgs e)
{
    int oCount = 1;
    foreach (object o in ParingItems.Children)
    {
        if (o.GetType() == typeof(ItemPairing))
        {
            MessageBox.Show(o.ToString());
            oCount++;
        }
    }
}

If you want to write effective WPF, then you should stop trying to use it like it was Windows Forms... WPF is all about data binding. You should take a look at the Data Binding Overview page on MSDN for an in depth introduction.

To answer your question, the general way for a UserControl to provide some data is for it to implement a DependencyProperty :

public static readonly DependencyProperty ResultsProperty = DependencyProperty.
    Register("Results", typeof(Dictionary<string, string>), 
    typeof(ItemPairing), new UIPropertyMetadata(Dictionary<string, string>.Empty));

public Dictionary<string, string> Results
{
    get { return (Dictionary<string, string>)GetValue(ResultsProperty); }
    set { SetValue(ResultsProperty, value); }
}

You didn't mention what type your Dictionary would be so I just assumed that it would be a Dictionary<string, string> .

Then you can Bind to this property from both inside and outside the UserControl :

<YourXmlNamespace:ItemPairing Results="{Binding YourExternalResultsProperty}" />

UPDATE >>>

You can handle the situation of aggregating the Results collections from multiple UserControl s by having a main view model which is set as the DataContext for the MainWindow . That view model can either contain multiple properties, one to bind to each UserControl Results property, or properties of the type of any other view models that you may be using.

Either way, by using a main view model like this, you should have a class that contains properties that bind to all of the Results collections, whether inside other view models or not, so you'll have access to them all. Then you could have a method that creates a new Dictionary from the values in all of the others.

Why not just add a public method to your control and return a dictionary?:

private Dictionary<string, string>

private void updateSE()
{
    selectExpr = this.fields1 + " = " + this.fields2;

    if (!this.dictionary.ContainsKey(this.fields1))
    {
        this.dictionary.Add(this.fields1, this.fields2);
    }
}

public Dictionary<string, string> GetPairSelections()
{
    return this.dictionary;
}

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