Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更新依赖项属性中的属性不会';看不见_C#_Wpf_Mvvm_Dependency Properties - Fatal编程技术网

C# 更新依赖项属性中的属性不会';看不见

C# 更新依赖项属性中的属性不会';看不见,c#,wpf,mvvm,dependency-properties,C#,Wpf,Mvvm,Dependency Properties,我有一门课,叫做宗族。氏族中的财产是一种杂音,默认为false 我看到了,克兰瑞。这具有类型为Clan的依赖项属性 在VM中,我有一个Clan类型的属性,它作为依赖属性传递到视图中: <UC:ClanUI Clan="{Binding Meilyr}" /> 在主视图中,以下是放置视图的方式: <UC:ClanUI Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" Clan="{Binding Meilyr}" />

我有一门课,叫做宗族。氏族中的财产是一种杂音,默认为false

我看到了,克兰瑞。这具有类型为Clan的依赖项属性

在VM中,我有一个Clan类型的属性,它作为依赖属性传递到视图中:

<UC:ClanUI Clan="{Binding Meilyr}" />
在主视图中,以下是放置视图的方式:

<UC:ClanUI Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" Clan="{Binding Meilyr}" />

下面是来自虚拟机的一些片段:

private Clan _Meilyr = new Clan();
    public Clan Meilyr
    {
        get
        {
            return _Meilyr;
        }
        set
        {
            _Meilyr = value;
            OnPropertyChanged("Meilyr");
        }
    }

...

private ICommand _ClanVoiced;
public ICommand ClanVoiced
{
    get
    {
        if (_ClanVoiced == null)
        {
            _ClanVoiced = new RelayCommand(ClanVoicedEx, null);
        }
        return _ClanVoiced;
    }
}
private void ClanVoicedEx(object p)
{
    if(Clans.FindAll(C => C.Voiced).Count >= 2)
    {
        //TODO
    }
    //Clans.First(C => C.Name == p.ToString()).Voiced = true; //<< This is how I will eventually be doing it, the next line was to ensure I was setting the correct thing.
    Meilyr.Voiced = true; //When debugging, when I click the image this line is hit, and after it has executed, inspecting Meilyr.Voiced shows it as being true.
}
私人氏族_Meilyr=新氏族();
公族梅里尔
{
收到
{
返回Meilyr;
}
设置
{
_Meilyr=值;
OnPropertyChanged(“Meilyr”);
}
}
...
私人ICommand(你的声音);;
公开命令
{
收到
{
如果(_ClanVoiced==null)
{
_ClanVoiced=新的RelayCommand(ClanVoicedEx,null);
}
回音(浊音);;
}
}
私有Voice索引(对象p)
{
if(Clans.FindAll(C=>C.Voiced.Count>=2)
{
//待办事项
}

//Clans.First(C=>C.Name==p.ToString()).Voiced=true;//请发布ViewModel代码


我假设您正在更新已更改的Clan属性,但未更改Voice属性。换句话说,Voiced需要是一个属性,其自身的属性已更改事件已触发。

确保
Clan
类实现
INotifyPropertyChanged
接口并引发
PropertyChanged
事件In Voiced属性的setter


由于您绑定到Clan.Voiced属性,因此定义Meilyr和clanVoiced属性的视图模型类是否实现了
INotifyPropertyChanged
接口并不重要。

能否显示实现
Clan.Voiced
的代码?也许是OnPropertyChanged的实现不正确。您是否异步设置Voiced的值?例如:您是否启动一个线程来做一些工作,然后在工作完成时设置
Clan.Voiced
的值。有时您可以在非ui线程上进行更改。有时您不能。最好的建议是始终更新ui线程上的视图模型属性。另一个想法。Do是否在控件上显式设置边框厚度?我认为这将覆盖样式中的setter。请参阅使用代码更新。Voiced有自己的onpropertychanged,并且作为以前的测试(现在从代码中删除),我尝试调用onpropertychanged(“Voiced”)在运行image clicked命令时,从VM手动在Clan实例上单击,但仍然没有。刚意识到我忘了添加此代码,我在原始帖子中添加了PropertyChanged和Voiced属性。据我所知,这一切都可以正常工作,但不是。Ohhhh…我现在看到了。我没有添加“:INotifyPropertyChan”ged’in…我现在觉得自己很蠢…编辑-当我把这个放进去的时候它就工作了…当然…>。
<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
    ...
    <Border BorderBrush="Red" Margin="5">
        <Image Source="{Binding Clan.Image, FallbackValue='../Media/Clans/Meilyr.png'}" Height="40" VerticalAlignment="Center">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseUp">
                    <i:InvokeCommandAction Command="{Binding DataContext.ClanVoiced, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding Clan.Name}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Image>
        <Border.Style>
            <Style TargetType="{x:Type Border}">
                <Setter Property="BorderThickness" Value="2" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Clan.Voiced}" Value="false">
                        <Setter Property="BorderThickness" Value="0" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
    </Border>
    ...
</Grid>
public Clan Clan
    {
        get { return (Clan)GetValue(ClanProperty); }
        set { SetValue(ClanProperty, value); }
    }
    public static readonly DependencyProperty ClanProperty =
        DependencyProperty.Register("Clan", typeof(Clan),
        typeof(ClanUI), new PropertyMetadata(null));
<UC:ClanUI Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2" Clan="{Binding Meilyr}" />
private Clan _Meilyr = new Clan();
    public Clan Meilyr
    {
        get
        {
            return _Meilyr;
        }
        set
        {
            _Meilyr = value;
            OnPropertyChanged("Meilyr");
        }
    }

...

private ICommand _ClanVoiced;
public ICommand ClanVoiced
{
    get
    {
        if (_ClanVoiced == null)
        {
            _ClanVoiced = new RelayCommand(ClanVoicedEx, null);
        }
        return _ClanVoiced;
    }
}
private void ClanVoicedEx(object p)
{
    if(Clans.FindAll(C => C.Voiced).Count >= 2)
    {
        //TODO
    }
    //Clans.First(C => C.Name == p.ToString()).Voiced = true; //<< This is how I will eventually be doing it, the next line was to ensure I was setting the correct thing.
    Meilyr.Voiced = true; //When debugging, when I click the image this line is hit, and after it has executed, inspecting Meilyr.Voiced shows it as being true.
}
private bool _Voiced = false; //<< When I default this to true instead, it displays how I expect in the view. Initial bindings seem to work fine. It just doesn't seem to know when Voiced changes for some reason...
public bool Voiced
{
    get
    {
        return _Voiced;
    }
    set
    {
        _Voiced = value;
        OnPropertyChanged("Voiced");
    }
}

...

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string propertyName)
{
    PropertyChangedEventHandler handler = PropertyChanged;

    if (handler != null)
    {
        if (handler.Target is CollectionView)
        {
            ((CollectionView)handler.Target).Refresh();
        }
        else
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

#endregion