0

我正在尝试使用 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>
...

图书馆虚拟机

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));
        }
    }

}

食谱虚拟机

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

4

2 回答 2

1

将您的 Textblock 绑定更改为 Text="{Binding Name}"

于 2017-04-18T08:36:51.557 回答
0

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

改为{x:Bind Name}工作{Binding Name},但不是因为有什么问题x:Bind,而是我对它的理解。

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

关于它的mode属性,文档说:

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

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

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

另一个很好的参考是这个问题的答案:Binding and x:Bind 之间的区别

于 2017-04-18T17:25:27.303 回答