簡體   English   中英

C#WPF綁定直到MouseOut才更新

[英]C# WPF Bindings not updating until MouseOut

我有一個帶有可單擊標簽(草和單位)的木板,當我單擊草標簽時,應將單位標簽移到草的x和y位置。 它有效,但是有點不對。 當我單擊標簽時,什么都沒有發生,直到我將光標移出所單擊的標簽,然后執行所需的行為。

XAML

<local:Grass Grid.Row="9" Grid.Column="16"   />
<local:Unit Grid.Row="{Binding Path=xPos, UpdateSourceTrigger=PropertyChanged}" Grid.Column="{Binding Path=yPos, UpdateSourceTrigger=PropertyChanged}" >
       <local:Unit.Background>
             <ImageBrush ImageSource="Images/tjej.png"/>
       </local:Unit.Background>
</local:Unit>

ObjectInspector

 public class ObjectInspector : INotifyPropertyChanged
{
    private int _xPos = 1, _yPos = 2;



    public int xPos
    {
        get { return _xPos; }
        set
        {
            _xPos = value;
            NotifyPropertyChanged("xPos");
        }
    }

    public int yPos
    {
        get { return _yPos; }
        set {
            _yPos = value;
            NotifyPropertyChanged("yPos");
        }
    }

    private string _type = "none";

    public string type
    {
        get { return _type; }
        set { 
            _type = value;
            NotifyPropertyChanged("type");
        }

    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            System.Diagnostics.Debug.WriteLine("property changed");

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

   public class Grass : Button
{

    protected override void OnClick()
    {
        base.OnClick();
        int x = (int)this.GetValue(Grid.RowProperty);
        int y = (int)this.GetValue(Grid.ColumnProperty);
        string type = this.GetType().Name;
        MainWindow.objectInspector.xPos = x;
        MainWindow.objectInspector.yPos = y;
        MainWindow.objectInspector.type = type;
    }
}

主窗口

  public partial class MainWindow : Window
{
    public static ObjectInspector objectInspector= new ObjectInspector();
    public MainWindow()
    {
        InitializeComponent();                       
        this.DataContext = objectInspector;


    }
}

有任何想法嗎?

編輯添加的MainWindow和Grass

編輯

嘗試注冊到公共事件處理程序, Click按鈕:

<local:Grass Grid.Row="9" Grid.Column="16"  Click="ClickEventHandler" />
...

在事件處理程序方法中,從發件人處獲取grass元素。


無論如何,我認為使用MVVM模式是更好的方法。 您可以設置GrassViewModelUnitViewModel 然后為每個創建一個DataTemplate 例如:

<DataTemplate DataType="{x:Type ViewModel:UnitViewModel}">
    ...Visual Elements Here...
</DataTemplate>

用於顯示網格中的元素的,您可以將ListBoxGrid as Items面板一起使用,如下所示:

<ListBox ItemsSource={Binding AllItemsCollection}>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid>
                ...rows and columns definitions here...
            </Grid>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <!--HERE THE ITEMS STYLE, HERE YOU SET THE COLUMN, ROW BINDINGS-->
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Grid.Row" Value="{Binding yPos}"/>
            <Setter Property="Grid.Column" Value="{Binding xPos}"/>
            <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

然后,您只需要在視圖模型中使用所需的所有元素創建AllItemsCollection 您可以使用行為來處理click事件,或為草創建UserControl(並在內部控制click事件):

<DataTemplate DataType="{x:Type ViewModel:UnitViewModel}">
    <GrassUserControl ...Inside the grass user control you can handler the click event.../>
</DataTemplate>

希望可以幫助...

如果您使用以下MVVM,則可以按如下所示將屬性附加到標簽。 您可以將此行為附加到任何從UIElement派生的控件

為MouseClick創建一個附加屬性

public class MouseClick
{
    public static readonly DependencyProperty MouseLeftClickProperty = 
        DependencyProperty.RegisterAttached("MouseLeftClick", typeof(ICommand), typeof(MouseClick),
        new FrameworkPropertyMetadata(CallBack));

    public static void SetMouseLeftClick(DependencyObject sender, ICommand value)
    {
        sender.SetValue(MouseLeftClickProperty, value);
    }

    public static ICommand GetMouseLeftClick(DependencyObject sender)
    {
        return sender.GetValue(MouseLeftClickProperty) as ICommand;
    }

    public static readonly DependencyProperty MouseEventParameterProperty =
        DependencyProperty.RegisterAttached(
            "MouseEventParameter",
            typeof(object),
            typeof(MouseClick),
            new FrameworkPropertyMetadata((object)null, null));


    public static object GetMouseEventParameter(DependencyObject d)
    {
        return d.GetValue(MouseEventParameterProperty);
    }


    public static void SetMouseEventParameter(DependencyObject d, object value)
    {
        d.SetValue(MouseEventParameterProperty, value);
    }

    private static void CallBack(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        if (sender != null)
        {
            UIElement element = sender as UIElement;
            if (element != null)
            {
                if (e.OldValue != null)
                {
                    element.RemoveHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(Handler));
                }
                if (e.NewValue != null)
                {
                    element.AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(Handler), true);
                }
            }
        }
    }
    private static void Handler(object sender, EventArgs e)
    {
        UIElement element = sender as UIElement;
        if (sender != null)
        {
            ICommand cmd = element.GetValue(MouseLeftClickProperty) as ICommand;
            if (cmd != null)
            {
                RoutedCommand routedCmd =cmd as RoutedCommand;
                object paramenter = element.GetValue(MouseEventParameterProperty);
                if (paramenter == null)
                {
                    paramenter = element;
                }
                if (routedCmd != null)
                {
                    if (routedCmd.CanExecute(paramenter, element))
                    {
                        routedCmd.Execute(paramenter, element);
                    }
                }
                else
                {
                    if (cmd.CanExecute(paramenter))
                    {
                        cmd.Execute(paramenter);
                    }
                }
            }
        }
    }
}

在您的Xaml中,如下附加viewModel的命令

 <Label Height="30" Width="200" Margin="10" Content="Click" local:MouseClick.MouseLeftClick="{Binding Click}" /> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM