WPF, связывающий несколько средств управления с другим datacontexts

Используйте это:

print("Shape Guesser Game \n-----------------")
print("Welcome to the Shape Guesser Game! \nI believe that I can guess the shape you think of.")
print("There is only 1 rule: \nYou can only think of a polygon with a maximum of 6 sides.")
response_1 = input("\nDo you want to play? \nPick Yes or No")
if response_1.lower() == "yes":
    print("Great! Let's get started! \n------------------")
    response_2 = input("Have you thought of your shape? Yes/No")
    if response_2.lower() == "yes":
        response_3 = input("How many sides does it have?")
        if response_3 == "3" or response_3 == "three":
            response_4 = input("How many equal sides does it have?")
            if response_4 == "2" or response_4 == "two":
                response_5 = input("Aha! It is an isosceles triangle! Am I right? Yes or No?")
                if response_5.lower() == "yes":
                    print("Yay I have succeeded! Thank you for playing this game. \nGo back to Home.")

            elif response_4 == "3" or response_4 == "three":
                response_6 = input("Aha! It is an equilateral triangle! Am I right? Yes or No?")
                print("Yay I have succeeded! Thank you for playing this game. \nGo back to Home.")

            else:
                print("Not valid:Error \n-------------")

        elif response_3 == "4" or response_3 == "four":
            response_7 = input("How many parallel sides does it have?")
            if response_7 == "two" or response_7 == "2":
                response_8 = input("Aha! It is a trapezium! Am I right? Yes or No?")
                if response_8.lower() == "yes":
                    print("Yay I have succeeded! Thank you for playing this game. \nGo back to Home.")
            if response_7 == "four" or response_7 == "4":
                response_9 = input("Aha! It is a parallelogram! Am I right? Yes or No?")
                if response_9.lower() == "yes":
                    print("Yay I have succeeded! Thank you for playing this game. \nGo back to Home.")

    elif response_2.lower() == "no":
        print("Okay no worries, I will give you more time!")

elif response_1.lower() == "no":
    print("Sad to see you go! Back to Home.")

or не работает так же, как if a == 'b' or 'c':, вы должны сделать это if a == 'b' or a == 'c':

Также такие вещи, как if response_1 == "Yes" or "yes", которые могут просто стать if response_1.lower() == "yes", поэтому YeS и yEs будет считаться 'yes'.

24
задан Alex 25 March 2009 в 01:46
поделиться

4 ответа

Я, возможно, думал бы об обертывании Вашего пользовательского объекта в отдельном классе, затем устанавливающем свойства DataContext подпанелей, которые содержат данные.

Например:

public class UserDataContext
{
  public UserInfo UserInfo { get; set; }
  public UserExtendedInfo UserExtendedInfo { get; set; }
}

Затем в Вашем UserControl.xaml:

<!-- Binding for the UserControl should be set in its parent, but for clarity -->
<UserControl DataContext="{Binding UserDataContext}">
  <StackPanel>
    <Grid DataContext="{Binding UserInfo}">
       <TextBlock Text="{Binding Email}" />
    </Grid>
    <Grid DataContext="{Binding UserExtendedInfo}">
       <TextBlock Text="{Binding Locale}" />
       <TextBlock Text="{Binding AboutMe}" />
    </Grid>
  </StackPanel>
</UserControl>

Это предполагает, что Ваш класс UserInfo имеет свойство электронной почты

и

То, что Ваш класс UserExtendedInfo имеет свойство Локали и AboutMe

31
ответ дан bendewey 28 November 2019 в 22:35
поделиться

Это - то, где M-V-VM входит очень удобный. Идея (насколько я понимаю, по крайней мере... все еще очень плохо мне знакомый) состоит в том, что само Окно связывается с классом "ViewModel". Класс ViewModel является просто классом, который представляет все данные способом, что Ваша вся страница имеет доступ ко всему, в чем это нуждается..., это просто объединяет все различные объекты, с которыми необходимо будет связать в одном классе..., и Вы устанавливаете DataContext Окна (или Page) к экземпляру этого класса. Ваши экземпляры UserInfo и UserInfoExtended являются общественными собственностями объекта ViewModel, и Вы просто используете Путь своего обязательного элемента для получения Вас через соответствующие свойства соответствующих объектов, с которыми Вы хотите связать каждое управление.

Существует великое (но довольно долго) видео, объясняя этот шаблон, и это проходит полный пример, который иллюстрирует много способов выполнить это и много различных причин, почему это - удобная и масштабируемая модель для использования в приложении WPF. Это также покрывает много функций WPF, а также введения во внедрение зависимости, которые являются очень соответствующими темами также, учитывая пример.

Вот ссылка на сообщение в блоге, которое содержит ссылку на видео, о котором я говорю:

Править: Сообщение в блоге было удалено (этот ответ довольно стар). Вот видео на YouTube:

https://www.youtube.com/watch? v=BRxnZahCPFQ

9
ответ дан Rich 28 November 2019 в 22:35
поделиться

Это самый простой метод из всех, и он работает очень хорошо.

В коде программной части, где вы устанавливаете контекст, просто используйте анонимный тип, содержащий все желаемые значения:

DataContext = new
{
  info = FetchUserInfoFromDatabase(),
  extendedInfo = FetchExtendedUserInfoFromDatabase(),
};

В XAML вы можете привязать к чему угодно:

<UserControl>
  <StackPanel>
    <TextBlock Text="{Binding info.Email}" />
    <TextBlock Text="{Binding extendedInfo.Locale} />
  ...

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

<UserControl>
  <StackPanel>
    <Grid DataContext="{Binding info}">
      <TextBlock Text={Binding Email}">
      ...
19
ответ дан 28 November 2019 в 22:35
поделиться

Как богатые, так и изогнутые были хорошие ответы. Изучая эту же тему сегодня в Silverlight вместо WPF, я обнаружил, что нет необходимости устанавливать несколько DataContexts. Пересматривая пример bendewey:

<UserControl DataContext="{Binding UserDataContext}">
  <StackPanel>
       <TextBlock Text="{Binding Path=UserInfo.Email}" />
       <TextBlock Text="{Binding Path=UserExtendedInfo.Locale}" />
       <TextBlock Text="{Binding Path=UserExtendedInfo.AboutMe}" />
  </StackPanel>
</UserControl>

Используя путь привязки, вы получаете возможность смешивать и сопоставлять привязки к свойствам различных классов, не обращая внимания на DataContext контейнеров элементов управления.

Вы также можете расширить возможности класса UserDataContext от bendewey, добавив свойства, которые манипулируют свойствами классов UserInfo и UserExtendedInfo. Вы можете, например, объединить имя и фамилию.

Вы можете реализовать INotifyPropertyChanged так, чтобы ваши элементы управления обновлялись при сбросе UserInfo и UserExtendedInfo.

Возможно, с архитектурной точки зрения предпочтительнее полностью изолировать базовые классы UserInfo и UserExtendedInfo от XAML, открыв требуемые свойства непосредственно в UserDataContext, тем самым устранив необходимость в привязке пути.

.
8
ответ дан 28 November 2019 в 22:35
поделиться
Другие вопросы по тегам:

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