简体   繁体   English

WPF中的MouseBinding手势未绑定到DataContext WPF

[英]MouseBinding Gesture in wpf not binding to DataContext wpf

I do not understand why my command is not properly executing when the user double clicks the listview item. 我不明白为什么用户双击列表视图项时我的命令不能正确执行。 I know for a fact the error occurs in the way it's binding. 我知道一个事实,即错误是在绑定方式中发生的。 I'm not sure how to properly bind to the windows data context. 我不确定如何正确绑定到Windows数据上下文。

How can I bind to the windows data context from a nested control. 如何从嵌套控件绑定到Windows数据上下文。

Here is the problematic code isolated... 这是孤立的有问题的代码...

<Grid.InputBindings>
    <MouseBinding Gesture="LeftDoubleClick" Command="{Binding EditCustomerCommand}"/>
</Grid.InputBindings>

MainWindow.xaml MainWindow.xaml

<Window.DataContext>
        <viewModel:MainWindowViewModel />
    </Window.DataContext>

    <!--<Grid>
        <ContentPresenter Content="{Binding ActiveViewModel}"></ContentPresenter>
    </Grid>-->


    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Button Grid.Row="0" Content="Add New Person" Command="{Binding AddNewPersonCommand}"/>
        <ListView Grid.Row="1" ItemsSource="{Binding People}">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="First Name" Width="150">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Grid Margin="0">
                                    <StackPanel Orientation="Horizontal">
                                        <Button Content="X" Width="20" 
                                                Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.RemovePersonCommand}"
                                                CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Self}}"
                                                />
                                        <Label  Content="{Binding FirstName}"/>
                                    </StackPanel>
                                    <Grid.InputBindings>
                                        <MouseBinding Gesture="LeftDoubleClick" Command="{Binding EditCustomerCommand}"/>
                                    </Grid.InputBindings>
                                </Grid>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>

            <ListView.Resources>
                <Style TargetType="{x:Type ListViewItem}">
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
                </Style>
            </ListView.Resources>

            <ListView.InputBindings>
                <KeyBinding Key="Delete" Command="{Binding DeleteCustomersCommand}"/>
            </ListView.InputBindings>

        </ListView>

        <StackPanel Grid.Row="2" Orientation="Horizontal">
            <Label Content="# People"/>
            <Label Content="{Binding PersonCount}"/>
        </StackPanel>

    </Grid>
</Window>

Please try the next solution, here I've used the freezable proxy class to get the access to the main view model. 请尝试下一个解决方案,这里我使用了freezable代理类来访问主视图模型。 This case is similar to your problem, since the column can't access its parent data context directly. 这种情况与您的问题类似,因为该列无法直接访问其父数据上下文。

Xaml code XAML代码

<Window x:Class="DataGridSoHelpAttempt.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:dataGridSoHelpAttempt="clr-namespace:DataGridSoHelpAttempt"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    Title="MainWindow" Height="350" Width="525" x:Name="This">
<Window.DataContext>
    <dataGridSoHelpAttempt:MainViewModel/>
</Window.DataContext>
<Grid x:Name="MyGrid">
    <Grid.Resources>
        <dataGridSoHelpAttempt:FreezableProxyClass x:Key="ProxyElement" ProxiedDataContext="{Binding Source={x:Reference This}, Path=DataContext}"/>
    </Grid.Resources>
    <DataGrid x:Name="MyDataGrid" ItemsSource="{Binding DataSource}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
            <DataGridTextColumn Header="Description" Binding="{Binding Description}"  Visibility="{Binding Source={StaticResource ProxyElement}, 
                Path=ProxiedDataContext.Visibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            <DataGridTextColumn Header="Comments" Binding="{Binding Comments}" Width="150"/>
            <DataGridTextColumn Header="Price (click to see total)" Binding="{Binding Price, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
        </DataGrid.Columns>
    </DataGrid>
    <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
        <Button Content="Show Description" Command="{Binding Command}"></Button>
    </StackPanel>
</Grid>

View model and models 查看模型和模型

    public class MainViewModel:BaseObservableObject
{
    private Visibility _visibility;
    private ICommand _command;
    private Visibility _totalsVisibility;
    private double _totalValue;

    public MainViewModel()
    {
        Visibility = Visibility.Collapsed;
        TotalsVisibility = Visibility.Collapsed;
        DataSource = new ObservableCollection<BaseData>(new List<BaseData>
        {
            new BaseData {Name = "Uncle Vania", Description = "A.Chekhov, play", Comments = "worth reading", Price = 25},
            new BaseData {Name = "Anna Karenine", Description = "L.Tolstoy, roman", Comments = "worth reading", Price = 35},
            new BaseData {Name = "The Master and Margarita", Description = "M.Bulgakov, novel", Comments = "worth reading", Price = 56},
        });
    }

    public ICommand Command
    {
        get
        {
            return _command ?? (_command = new RelayCommand(VisibilityChangingCommand));
        }
    }

    private void VisibilityChangingCommand()
    {
        Visibility = Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
    }

    public ObservableCollection<BaseData> DataSource { get; set; }

    public Visibility Visibility
    {
        get { return _visibility; }
        set
        {
            _visibility = value;
            OnPropertyChanged();
        }
    }

    public ObservableCollection<BaseData> ColumnCollection
    {
        get { return DataSource; }
    }

    public Visibility TotalsVisibility
    {
        get { return _totalsVisibility; }
        set
        {
            _totalsVisibility = value;
            OnPropertyChanged();
        }
    }

    public double TotalValue
    {
        get { return ColumnCollection.Sum(x => x.Price); }
    }

}

public class BaseData:BaseObservableObject
{
    private string _name;
    private string _description;
    private string _comments;
    private int _price;

    public virtual string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    public virtual object Description
    {
        get { return _description; }
        set
        {
            _description = (string) value;
            OnPropertyChanged();
        }
    }

    public string Comments
    {
        get { return _comments; }
        set
        {
            _comments = value;
            OnPropertyChanged();
        }
    }

    public int Price
    {
        get { return _price; }
        set
        {
            _price = value;
            OnPropertyChanged();
        }
    }
}

Freezable proxy code 可冻结的代理代码

 public class FreezableProxyClass : Freezable
{
    protected override Freezable CreateInstanceCore()
    {
        return new FreezableProxyClass();
    }


    public static readonly DependencyProperty ProxiedDataContextProperty = DependencyProperty.Register(
        "ProxiedDataContext", typeof (object), typeof (FreezableProxyClass), new PropertyMetadata(default(object)));

    public object ProxiedDataContext
    {
        get { return (object) GetValue(ProxiedDataContextProperty); }
        set { SetValue(ProxiedDataContextProperty, value); }
    }
}

All is done due to the freezable object code, please take the solution as the starting point to your research. 一切都取决于可冻结的对象代码,因此请以解决方案作为您研究的起点。 I'll glad to help if you will have problems with the code. 如果您的代码有问题,我们将很乐意为您提供帮助。

Regards. 问候。 I'll glad to help you 我很乐意为您服务

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM