可点击按钮获取数据wpf mvvm

时间:2018-05-08 01:59:15

标签: c# wpf mvvm

View.Xaml

 <Grid>
        <ListView ItemsSource = "{Binding Path = dcCategory}" SelectedValuePath = "Key" SelectedValue = "{Binding Path = Category, Mode = TwoWay}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <StackPanel Orientation="Horizontal" >
                            <Button Content="Add Value" Command="{Binding Path=DataContext.AddValue, RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type ListView}}}"/>
                            <TextBlock Text="{Binding Path=Key.Name}"/>
                        </StackPanel>
                        <ListBox ItemsSource="{Binding Path=Value}" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>
    </Grid>

我的目标是点击添加价值并发送所选项目(类别类型)。它现在正在运作,但不像我所说的那样。 只需点击按钮,我就必须先点击第一个蓝色区域,然后编码并抓住&#39; &#39;类别&#39;有数据。否则Category为null。

example

视图模型

private Category _Category;
public Category Category
{
    get
    {
        return _Category;
    }
    set
    {
        if (_Category != value)
        {
            _Category = value;
            OnPropertyChanged(() => Category);
        }
    }
}

    public ICommand AddValue
    {
        get
        {
            if (_AddValue == null)
            {
                _AddValue = new BaseCommand(() => Messenger.Default.Send(CategoryValueCode.AddValue + "," + Category.CategoryId));
            }
            return _AddValue;
        }
    }

2 个答案:

答案 0 :(得分:0)

这个逻辑,因为你的按钮命令将在设置ListView.SelectedValue之前执行。如果您为PreviewMouseDown处理Button,则可以对其进行更改。我还发现将ListView.SelectionMode设置为Single会更好。

<ListView ItemsSource = "{Binding Path = dcCategory}" SelectedValuePath = "Key" SelectedValue = "{Binding Path = Category, Mode = TwoWay}" SelectionMode="Single">
<Button Content="Add Value" Command="{Binding Path=DataContext.AddValue, RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" PreviewMouseDown="PreviewMouseDown"/>


private void PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    ListViewItem lvi = null;
    var visParent = VisualTreeHelper.GetParent(sender as FrameworkElement);
    while (lvi == null && visParent != null)
    {
        lvi = visParent as ListViewItem;
        visParent = VisualTreeHelper.GetParent(visParent);
    }
    if (lvi == null) { return; }
    lvi.IsSelected = true;
}

答案 1 :(得分:0)

  • 我没有检查 Rekshino 解决方案

  • 感谢您提示,与此同时,在解决问题的过程中,我做了很多更改,完全改变了viewmodel / view。 我以这种方式实现了我的目标:

查看:

<Grid>
        <ItemsControl ItemsSource = "{Binding listCategoryAddValue}" >
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <StackPanel Orientation="Horizontal">
                            <Button Content="Add Value" Command="{Binding Path=AddValue}"/> 
                            <TextBlock Text="{Binding Category.Name}"/>
                        </StackPanel>
                        <ListBox ItemsSource="{Binding ValueList}" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal">
                    </StackPanel>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Grid>

<强>视图模型:

public class CategoriesViewModel : WszystkieViewModel<CategoryAddValue>
    {
        #region Fields & Properties
        private ObservableCollection<CategoryAddValue> _listCategoryAddValue;
        public ObservableCollection<CategoryAddValue> listCategoryAddValue
        {
            get
            {
                if (_listCategoryAddValue == null) { Load(); }
                return _listCategoryAddValue;
            }
            set
            {
                if (_listCategoryAddValue != value)
                {
                    _listCategoryAddValue = value;
                    OnPropertyChanged(() => listCategoryAddValue);
                }
            }
        }
        #endregion Fields & Properties

        #region Constructor
        public CategoriesViewModel() : base()
        {
            base.DisplayName = "Kategorie";
        }
        #endregion Constructor

        #region Helpers
        private void SendValue(int CategoryId)
        {
            Messenger.Default.Send(CategoryValueCode.AddValue + "," + CategoryId);
        }

        public override void Load()
        {
            var allCategories = (from k in db.Category select k).ToList();
            _listCategoryAddValue = new ObservableCollection<CategoryAddValue>();

            foreach (var i in allCategories)
            {
                _listCategoryAddValue.Add(new CategoryAddValue(new RelayCommand(() => SendValue(i.KategoriaId)))
                {
                    Category = i,
                    ValueList = db.CategoryValue.Where(x => x.CategoryId== i.CategoryId).Select(x => x.Value).ToList()
                });
            }
        }
        #endregion Helpers
    }

<强>模型

public class CategoryAddValue
{
    public Category Category { get; set; }
    public List<string> ValueList { get; set; }

    private ICommand _addValue;
    public ICommand AddValue
    {
        get
        {
            return _addValue;
        }
    }

    public CategoryAddValue(RelayCommand command)
    {
        _addValue = command;
    }
}