2014-10-28 4 views
1

В настоящее время я разрабатываю универсальное приложение в C#/XAML с MVVM (не MVVM Light), и у меня возникают проблемы с частью XAML.Видимость StackPanel не обновляется при изменении свойства зависимостей

Я бы хотел отобразить тот или иной StackPanel, когда свойство зависимости изменилось в моей модели ViewModel. Я думаю, что код говорит сам за себя.

<StackPanel Visibility="{Binding MyProperty, Converter={StaticResource BooleanToVisibilityConverter}}"> 
    <!-- Some content --> 
</StackPanel> 

<StackPanel Visibility="{Binding MyProperty, Converter={StaticResource InvertBooleanToVisibilityConverter}}"> 
    <!-- Some another content --> 
</StackPanel> 

И вот определение свойства зависимости.

public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register(
    "MyProperty", 
    typeof (bool), 
    typeof (MyViewModel), 
    new PropertyMetadata(true)); 

public bool MyProperty 
{ 
    get { return (bool) GetValue(MyPropertyProperty); } 
    set { SetValue(MyPropertyProperty, value); OnPropertyChanged(); // Implemented by ReSharper } 
} 

Я думаю, вы понять это, что MyProperty является логическим, что преобразовать в Visibility через преобразователи. Таким образом, когда MyProperty изменено в ViewModel, представление не обновляется.

Я уже пытался использовать свойство UpdateSourceTrigger, но он не работает. Кроме того, у меня нет ошибок привязки, и конвертеры работают нормально (я вижу только один StackPanel при запуске приложения).

Пожалуйста, имейте в виду, что я не хочу использовать код за частью, если нет другого решения.

Благодарим за помощь.

+0

Можете ли вы добавить определение своего свойства зависимостей? –

+0

Вы уведомите об изменении недвижимости? –

+0

@AaronHawkins: Конечно. Я только что отредактировал начальную должность. – Atlasmaybe

ответ

1

Я, наконец, сдался и использовал код позади части, и теперь он работает нормально ,

0

Ваши <StackPanel> s часть некоторого UserControl? Если нет, то почему вы используете DependencyProperty?

Ваша реализация совсем не работает.

Давайте предположим на минуту, что это не является частью пользовательского элемента управления (поправьте меня, - если я не прав, я буду переписывать решение)

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

Это образец ViewModel с (один) свойства 1

using Windows.UI.Xaml; 
using System.ComponentModel; 

// very simple view model 
class MyViewModel : DependencyObject, INotifyPropertyChanged 
{ 

    // implement INotifyPropertyChanged 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    // register 
    public static DependencyProperty FooterTitleProperty = DependencyProperty.Register("FooterTitle", typeof(string), typeof(MyViewModel), 
     new PropertyMetadata(string.Empty, OnFooterTitlePropertyChanged)); 

    // the actual property 
    public string FooterTitle 
    { 
     get { return (string) GetValue(FooterTitleProperty); } 
     set 
     { 
      SetValue(FooterTitleProperty, value); 
     } 
    } 

    // this will fire when the property gets change 
    // it will call the OnPropertyChanged to notify the UI element to update its layout 
    private static void OnFooterTitlePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
    { 
     MyViewModel mvm = dependencyObject as MyViewModel; 
     mvm.OnPropertyChanged("FooterTitle"); 
    } 
} 

Чтобы проверить код, который мы будем делать очень простую форму XAML

<Grid x:Name="ContentPanel"> 
    <StackPanel> 
     <TextBlock x:Name="tb" Text="{Binding FooterTitle}" FontSize="48"></TextBlock> 
     <Button Content="Test Property" Click="Button_Click_1"></Button> 
    </StackPanel> 
</Grid> 

При нажатии на мы изменим текст текстового поля

public sealed partial class MainPage : Page 
{ 
    // create the view model 
    MyViewModel vm = new MyViewModel(); 

    public MainPage() 
    { 
     this.InitializeComponent(); 

     this.NavigationCacheMode = NavigationCacheMode.Required; 


     // set the text we initial want to display 
     vm.FooterTitle = "default text"; 

     // set the DataContext of the textbox to the ViewModel 
     tb.DataContext = vm; 
    } 


    // after the button is click we change the TextBox's Text 
    private void Button_Click_1(object sender, RoutedEventArgs e) 
    { 
     // change the text 
     vm.FooterTitle = "Test Property Has Changed."; 

     // what happens is the Setter of the Property is called first 
     // after that happens it launches the `OnFooterTitlePropertyChanged` event 
     // that we hook up with the Register function. 


     // `OnFooterTitlePropertyChanged` launches the INotifyPropertyChanged event 
     // then finally the TextBox will updates it's layout 
    } 
} 

На этом этапе вы можете догадаться, что вам действительно не нужен DependencyProperty и сказать, почему я не могу просто запустить INotifyPropertyChanged в Setter вместо этого? Ну, вы можете, и это, вероятно, предпочтительный метод.

Если все это является частью UserControl, то я могу видеть, используя DependencyProperty то в OnFooterTitlePropertyChanged случае вы можете установить

name_of_textbox.Text = FooterTitle; 
+0

Спасибо за ваш ответ, но это не то, что я ищу. Чтобы быть наиболее интересным, в настоящее время мои 'StackPanel' не являются частью пользовательского 'UserControl', но они будут позже (я нахожусь на ранней стадии разработки). Кроме того, я хотел бы избежать использования кода за частью, потому что это универсальное приложение, и я не хочу копировать/вставлять код. Конечно, если будет какое-то другое решение, я сделаю, как вы сказали. – Atlasmaybe

+0

@Atlasmaybe Отсутствует код (это было просто для проверки виртуальной машины). Эта виртуальная машина может быть частью общего проекта. Замените TextBox на StackPanel, и вы увидите, что после изменения вашего свойства он запустит ваш конвертер. Пример, который я закодировал, заключался в том, чтобы привести вас в правильное направление, потому что ваш вопрос и образец кода имеют очень мало смысла. –

+0

Я проанализировал ваш код, и он такой же, как у меня: у вас есть одна простая виртуальная машина с DP, простой вид. Различия находятся в запуске события OnPropertyChanged() '' и 'ButtonClickEvent' (который является частью кода позади созданной вами страницы), который вы используете для изменения свойства, тогда как моя изменена в виртуальной машине. Я ценю усилия, которые вы дали, чтобы поставить меня в «правильном направлении», но я не думаю, что это поможет, если у нас будет тот же код. – Atlasmaybe

Смежные вопросы