Двумя путями привязка данных со словарем в WPF

where + drop_duplicates

df['key'] = df['t_num'].where(df['o_st'].eq('P'), df['r_num'])

df.drop_duplicates(subset=['A_key', 'key']).drop('key', 1)

    A_key  t_num r_num o_st
292    A1     16    TS    Q
173    A5     15    TT    Q
955    A7     19    TQ    Q
804    A7     17    TR    Q
668    A1     28  None    P
788    A4     88  None    P
693    A7     17    TS    Q
781    A1     22  None    P
<час>

У вас есть два отдельных подмножества, которые вы хотите проверить на уникальность в зависимости от значения третьего колонка. Вместо того, чтобы дважды вызывать drop_duplicates, я создаю маску, которая содержит правильное значение подмножества, прежде чем вызывать drop_duplicates один раз.

25
задан Community 23 May 2017 в 12:34
поделиться

3 ответа

Это немного глупо, но я заставил его работать (при условии, что я понимаю, что вы хотите).

Сначала я создал класс модели представления:

class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        this.data.Add(1, "One");
        this.data.Add(2, "Two");
        this.data.Add(3, "Three");
    }

    Dictionary<int, string> data = new Dictionary<int, string>();
    public IDictionary<int, string> Data
    {
        get { return this.data; }
    }

    private KeyValuePair<int, string>? selectedKey = null;
    public KeyValuePair<int, string>? SelectedKey
    {
        get { return this.selectedKey; }
        set
        {
            this.selectedKey = value;
            this.OnPropertyChanged("SelectedKey");
            this.OnPropertyChanged("SelectedValue");
        }
    }

    public string SelectedValue
    {
        get
        {
            if(null == this.SelectedKey)
            {
                return string.Empty;
            }

            return this.data[this.SelectedKey.Value.Key];
        }
        set
        {
            this.data[this.SelectedKey.Value.Key] = value;
            this.OnPropertyChanged("SelectedValue");
        }
    }

    public event PropertyChangedEventHandler  PropertyChanged;
    private void OnPropertyChanged(string propName)
    {
        var eh = this.PropertyChanged;
        if(null != eh)
        {
            eh(this, new PropertyChangedEventArgs(propName));
        }
    }
}

А затем в XAML:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ListBox x:Name="ItemsListBox" Grid.Row="0"
            ItemsSource="{Binding Path=Data}"
            DisplayMemberPath="Key"
            SelectedItem="{Binding Path=SelectedKey}">
        </ListBox>
        <TextBox Grid.Row="1"
            Text="{Binding Path=SelectedValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    </Grid>
</Window>

Значение свойства Data привязано к ItemsSource из ListBox. Как вы указали в вопросе, это приводит к использованию экземпляров KeyValuePair<int, string> в качестве данных за ListBox. Я установил DisplayMemberPath на Key, чтобы значение клавиши использовалось в качестве отображаемого значения для каждого элемента в ListBox.

Как вы обнаружили, вы не можете просто использовать Value из KeyValuePair в качестве данных для TextBox, так как это только для чтения. Вместо этого TextBox привязывается к свойству в модели представления, которое может получить и установить значение для выбранного в данный момент ключа (которое обновляется путем привязки свойства SelectedItem в ListBox к другому свойству в модели представления ). Мне пришлось сделать это свойство обнуляемым (поскольку KeyValuePair является структурой), чтобы код мог обнаруживать, когда выбора нет.

В моем тестовом приложении это, кажется, привело к правке TextBox, распространяющейся на Dictionary в модели представления.

1125 Это более или менее то, что вы собираетесь? Кажется, что это должно быть немного чище, но я не уверен, есть ли способ сделать это.

6
ответ дан 28 November 2019 в 21:45
поделиться

Вместо

Dictionary<string, int>

вы можете иметь

Dictionary<string, IntWrapperClass>?

В IntWrapperClass реализован INotifyPropertyCHanged. Затем вы можете иметь двустороннюю привязку Listview / Listbox к элементам в словаре.

0
ответ дан 28 November 2019 в 21:45
поделиться

A good start is to decide what do you and do you not want to accept as an email address?

99% of of email addresses look like this: bob.smith@foo.com or fred@bla.edu

However, it's technically legal to have an email address like this: f!#$%&'*+-/=?^_{|}~"ha!"@com

There are probably only a handful of valid emails in the world for top-level domains, and almost nobody uses most of those other characters (especially quotes and backticks), so you might want to assume that these are all invalid things to do. But you should do so as a conscious decision.

Beyond that, do what Paul says and try to match the input to a regular expression like this: ^[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,}$

That one will match pretty much everybody's email address.

Пользовательский класс

public class MyCustomClass
{
    public string Key { get; set; }
    public int Value { get; set; }
}

Set ItemsSource

ObservableCollection<MyCustomClass> dict = new ObservableCollection<MyCustomClass>();
dict.Add(new MyCustomClass{Key = "test", Value = 1});
dict.Add(new MyCustomClass{ Key = "test2", Value = 2 });
listView.ItemsSource = dict;

XAML

<Window.Resources>
    <DataTemplate x:Key="ValueTemplate">
        <TextBox Text="{Binding Value}" />
    </DataTemplate>
</Window.Resources>
<ListView Name="listView">
    <ListView.View>
        <GridView>
            <GridViewColumn CellTemplate="{StaticResource ValueTemplate}"/>
        </GridView>
    </ListView.View>
</ListView>
20
ответ дан 28 November 2019 в 21:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: