在UWP社区工具包的MasterDetailsView

时间:2017-04-16 17:27:15

标签: uwp uwp-xaml windows-community-toolkit

我正在尝试使用UWP社区工具包MasterDetailsView来提供编辑界面。但是,当我进行更改时,我似乎无法在其列表视图中获取单个项目来更新其属性。

这是我用来连接控件的XAML的一部分:

        <controls:MasterDetailsView x:Name="masterDetailsView" Foreground="Black"
                                ItemsSource="{x:Bind libraryVM.Recipes, Mode=TwoWay}"
                                SelectedItem="{x:Bind libraryVM.SelectedRecipe, Mode=TwoWay}"
                                NoSelectionContent="Select an item to view">
        <controls:MasterDetailsView.ItemTemplate>
            <DataTemplate x:DataType="recipes:RecipeVM">
                <StackPanel Margin="0,8">
                    <TextBlock Style="{ThemeResource SubtitleTextBlockStyle}"
                               Text="{x:Bind Name}" />
                </StackPanel>
            </DataTemplate>
        </controls:MasterDetailsView.ItemTemplate>
...

LibraryVM

public class LibraryVM : INotifyPropertyChanged
{
    Library library;
    ObservableCollection<RecipeVM> _Recipes;
    public event PropertyChangedEventHandler PropertyChanged;

    public LibraryVM()
    {
        library = new Library();
        _Recipes = new ObservableCollection<RecipeVM>();
        foreach (var rec in library.Recipes)
        {
            var recipe = _Recipes.FirstOrDefault(r => r.Id == rec.Id);

            if (recipe == null)
            {
                var r = new RecipeVM(rec);
                _Recipes.Add(r);
            }
            else
            {
                recipe.Name = rec.Name;
                recipe.Description = rec.Description;
            }
        }
    }

    public ObservableCollection<RecipeVM> Recipes
    {
        get { return _Recipes; }
        set
        {
            _Recipes = value;
            OnPropertyChanged();
        }
    }

    RecipeVM _SelectedRecipe;


    public RecipeVM SelectedRecipe
    {
        get
        {
            return _SelectedRecipe;
        }

        set
        {
            _SelectedRecipe = value;
            OnPropertyChanged();
        }
    }

    public void SaveChanges()
    {
        if (_SelectedRecipe.Id == Guid.Empty)
        {
            library.CreateNew(_SelectedRecipe.Recipe);
        }
        else
        {
            library.SaveChanges(_SelectedRecipe.Recipe);
        }
    }

    void OnPropertyChanged([CallerMemberName]string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

RecipeVM

public class RecipeVM : INotifyPropertyChanged
{
    Recipe _recipe;
    Recipe _backup;
    public event PropertyChangedEventHandler PropertyChanged;

    public Recipe Recipe
    {
        get
        {
            return _recipe;
        }
    }

    public RecipeVM(Recipe recipe = null)
    {
        _recipe = recipe;

        if(_recipe == null)
        {
            _recipe = new Recipe();
            _recipe.Name = "New Recipe";
        }

        this.IsEditing = false;
    }

    public Guid Id
    {
        get
        {
            return _recipe.Id;
        }

        set
        {
            _recipe.Id = value;
            OnPropertyChanged();
        }
    }

    bool _IsEditing;


    public bool IsEditing
    {
        get
        {
            return _IsEditing;
        }

        set
        {
            _IsEditing = value;
            OnPropertyChanged();
        }
    }

    public string Name
    {
        get
        {
            return _recipe.Name;
        }

        set
        {
            _recipe.Name = value;
            OnPropertyChanged();
        }
    }

    public string Description
    {
        get
        {
            return _recipe.Description;
        }

        set
        {
            _recipe.Description = value;
            OnPropertyChanged();
        }
    }

    public void MakeBackup()
    {
        _backup = new Recipe()
        {
            Id = _recipe.Id,
            Name = _recipe.Name,
            Description = _recipe.Description
        };
    }

    public void RestoreBackup()
    {
        Name = _backup.Name;
        Description = _backup.Description;
    }

    void OnPropertyChanged([CallerMemberName]string propertyName = "")
    {
        if(PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

然而,当我更新任何RecipeVM项目时,我似乎无法在MasterDetailsView的ListView中获取它的相应项目进行更新。我相信我已经在任何地方实施了INotifyPropertyChanged,但我显然错过了一些东西。

更新 我已经确认绑定在其他地方都有效。如果我在更改后单步执行代码,则RecipeVM和基础Recipe会相应更新。

2 个答案:

答案 0 :(得分:1)

将Textblock绑定更改为Text =&#34; {Binding Name}&#34;

答案 1 :(得分:0)

感谢Chirag Shah,他让我指向了正确的方向。

{x:Bind Name}更改为{Binding Name}有效,但不是因为x:Bind有任何问题,而是我对它的理解。

我缺少的是x:Bind默认为更加保守的绑定模式。

关于它是mode属性,the documentation说:

  

指定绑定模式,作为以下字符串之一:“OneTime”,“OneWay”或“TwoWay”。默认为“OneTime”。请注意,这与{Binding}的默认值不同,在大多数情况下为“OneWay”。

更新我的XAML以明确声明该模式解决了问题。

<TextBlock Style="{ThemeResource SubtitleTextBlockStyle}"
    Text="{x:Bind Name, Mode=OneWay}" />

另一个很好的参考是这个问题的答案:Difference between Binding and x:Bind